aboutsummaryrefslogtreecommitdiffstats
path: root/main/nfs-utils
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2014-08-06 09:52:50 +0300
committerTimo Teräs <timo.teras@iki.fi>2014-08-06 09:54:46 +0300
commit87c34001006b65b2be65cb87168b498c915390e1 (patch)
treebba7637346cb2a8a230234fc1c04b481f88e372a /main/nfs-utils
parent910ce2ae3ff7e550d4f532c7d74d3e96526bc368 (diff)
downloadaports-87c34001006b65b2be65cb87168b498c915390e1.tar.bz2
aports-87c34001006b65b2be65cb87168b498c915390e1.tar.xz
main/nfs-utils: upgrade to 1.3.1-rc3 and refresh musl patches
use patch series sent to linux-nfs mailing list, and add one more patch to address accessing /proc/net/rpc.
Diffstat (limited to 'main/nfs-utils')
-rw-r--r--main/nfs-utils/0001-conffile-use-standard-uint-_t-and-unsigned-char.patch6
-rw-r--r--main/nfs-utils/0002-Fix-header-include-for-definition-of-NULL.patch6
-rw-r--r--main/nfs-utils/0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch30
-rw-r--r--main/nfs-utils/0004-replace-__attribute_malloc__-with-the-more-portable-.patch (renamed from main/nfs-utils/0003-replace-__attribute_malloc__-with-the-more-portable-.patch)6
-rw-r--r--main/nfs-utils/0005-exportfs-define-_GNU_SOURCE-for-stat64.patch28
-rw-r--r--main/nfs-utils/0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch29
-rw-r--r--main/nfs-utils/0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch38
-rw-r--r--main/nfs-utils/0006-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch (renamed from main/nfs-utils/0007-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch)6
-rw-r--r--main/nfs-utils/0007-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch (renamed from main/nfs-utils/0004-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch)17
-rw-r--r--main/nfs-utils/0008-Only-work-around-glibc-bugs-on-glibc.patch (renamed from main/nfs-utils/0001-Only-work-around-glibc-bugs-on-glibc.patch)5
-rw-r--r--main/nfs-utils/0009-include-libgen.h-for-basename.patch (renamed from main/nfs-utils/0001-include-libgen.h-for-basename.patch)6
-rw-r--r--main/nfs-utils/0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch49
-rw-r--r--main/nfs-utils/0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch39
-rw-r--r--main/nfs-utils/0012-rework-access-to-proc-net-rpc.patch1196
-rw-r--r--main/nfs-utils/APKBUILD140
-rw-r--r--main/nfs-utils/nfs-utils-1.3.1-rc3.patch1086
16 files changed, 2534 insertions, 153 deletions
diff --git a/main/nfs-utils/0001-conffile-use-standard-uint-_t-and-unsigned-char.patch b/main/nfs-utils/0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
index fdd76c71b6..2be3602ac7 100644
--- a/main/nfs-utils/0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
+++ b/main/nfs-utils/0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
@@ -1,7 +1,7 @@
-From ae1a0a0fd0191ccc7dd4bbbf0a1803db0bd7ccca Mon Sep 17 00:00:00 2001
+From 733f0786ee7fb6091e35827a7ba1c1c96a7b393d Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 12 Feb 2014 13:40:36 +0000
-Subject: [PATCH 1/7] conffile: use standard uint*_t and unsigned char
+Subject: [PATCH] conffile: use standard uint*_t and unsigned char
Use the standard integer types. This fixes compiling errors with musl
libc.
@@ -70,5 +70,5 @@ index c3434d5..6b94ec0 100644
while (*buf) {
if (*buf > 127 || (c1 = asc2bin[*buf]) == 255)
--
-1.8.5.3
+2.0.4
diff --git a/main/nfs-utils/0002-Fix-header-include-for-definition-of-NULL.patch b/main/nfs-utils/0002-Fix-header-include-for-definition-of-NULL.patch
index ba7c56c44a..ef359b9759 100644
--- a/main/nfs-utils/0002-Fix-header-include-for-definition-of-NULL.patch
+++ b/main/nfs-utils/0002-Fix-header-include-for-definition-of-NULL.patch
@@ -1,7 +1,7 @@
-From 7bb18315852601df9fd02f714d12fa09b9adbdba Mon Sep 17 00:00:00 2001
+From bf56f9f7a782a8b854f698bf2b452c790ebc2e93 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 12 Feb 2014 13:43:34 +0000
-Subject: [PATCH 2/7] Fix header include for definition of NULL
+Subject: [PATCH] Fix header include for definition of NULL
NULL is defined in stdlib.h so we need to include that.
@@ -23,5 +23,5 @@ index a1c30f9..446b537 100644
#include <sys/socket.h>
#include <netinet/in.h>
--
-1.8.5.3
+2.0.4
diff --git a/main/nfs-utils/0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch b/main/nfs-utils/0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch
new file mode 100644
index 0000000000..40163bf8a7
--- /dev/null
+++ b/main/nfs-utils/0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch
@@ -0,0 +1,30 @@
+From 3c09cd3801d1200a11e03a387cd4844591b7850d Mon Sep 17 00:00:00 2001
+From: Natanael Copa <ncopa@alpinelinux.org>
+Date: Tue, 5 Aug 2014 17:02:25 +0200
+Subject: [PATCH] configure.ac: enable GNU_SOURCE for stat64/statfs64
+
+Use AC_USE_SYSTEM_EXTENSIONS to enable GNU_SOURCE, which is needed
+for:
+ - stat64 in utils/exportfs/exportfs.c
+ - statfs64 in utils/mountd/cache.c
+
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
+---
+ configure.ac | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/configure.ac b/configure.ac
+index 408f4c8..b9682ed 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -8,6 +8,7 @@ AM_INIT_AUTOMAKE
+ AC_PREREQ(2.59)
+ AC_PREFIX_DEFAULT(/usr)
+ AM_MAINTAINER_MODE
++AC_USE_SYSTEM_EXTENSIONS
+
+ dnl *************************************************************
+ dnl * Define the set of applicable options
+--
+2.0.4
+
diff --git a/main/nfs-utils/0003-replace-__attribute_malloc__-with-the-more-portable-.patch b/main/nfs-utils/0004-replace-__attribute_malloc__-with-the-more-portable-.patch
index 569acede0c..f92e1df6d4 100644
--- a/main/nfs-utils/0003-replace-__attribute_malloc__-with-the-more-portable-.patch
+++ b/main/nfs-utils/0004-replace-__attribute_malloc__-with-the-more-portable-.patch
@@ -1,7 +1,7 @@
-From 1364f15b4b5654da8af64fc8e77bb184115ad445 Mon Sep 17 00:00:00 2001
+From c09597e62a4fcd68fa4aab1183146d36c0326a35 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 12 Feb 2014 13:46:51 +0000
-Subject: [PATCH 3/7] replace __attribute_malloc__ with the more portable
+Subject: [PATCH] replace __attribute_malloc__ with the more portable
__attribute__((__malloc__))
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
@@ -204,5 +204,5 @@ index e89e666..a1d8035 100644
extern void my_svc_run(void);
--
-1.8.5.3
+2.0.4
diff --git a/main/nfs-utils/0005-exportfs-define-_GNU_SOURCE-for-stat64.patch b/main/nfs-utils/0005-exportfs-define-_GNU_SOURCE-for-stat64.patch
deleted file mode 100644
index 29f094ca0b..0000000000
--- a/main/nfs-utils/0005-exportfs-define-_GNU_SOURCE-for-stat64.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 2ab92ce00f420d98e10f2b04eee229ffcf540015 Mon Sep 17 00:00:00 2001
-From: Natanael Copa <ncopa@alpinelinux.org>
-Date: Wed, 12 Feb 2014 14:00:50 +0000
-Subject: [PATCH 5/7] exportfs: define _GNU_SOURCE for stat64
-
-Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
----
- utils/exportfs/exportfs.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
-index 8c86790..1feadaa 100644
---- a/utils/exportfs/exportfs.c
-+++ b/utils/exportfs/exportfs.c
-@@ -12,6 +12,10 @@
- #include <config.h>
- #endif
-
-+#ifndef _GNU_SOURCE
-+#define _GNU_SOURCE
-+#endif
-+
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/vfs.h>
---
-1.8.5.3
-
diff --git a/main/nfs-utils/0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch b/main/nfs-utils/0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch
new file mode 100644
index 0000000000..e9c666954f
--- /dev/null
+++ b/main/nfs-utils/0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch
@@ -0,0 +1,29 @@
+From f16907e3a179438ff93e712d5303d8041f918dbe Mon Sep 17 00:00:00 2001
+From: Natanael Copa <ncopa@alpinelinux.org>
+Date: Wed, 12 Feb 2014 14:04:30 +0000
+Subject: [PATCH] mountd: use standard dev_t instead of glibc internals
+
+The __dev_t is a GNU libc internal. Use the standard dev_t instead,
+which is specified in POSIX.
+
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
+---
+ utils/mountd/cache.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
+index b0cc6a8..663a52a 100644
+--- a/utils/mountd/cache.c
++++ b/utils/mountd/cache.c
+@@ -1419,7 +1419,7 @@ static int cache_export_ent(char *domain, struct exportent *exp, char *path)
+ */
+ struct stat stb;
+ size_t l = strlen(exp->e_path);
+- __dev_t dev;
++ dev_t dev;
+
+ if (strlen(path) <= l || path[l] != '/' ||
+ strncmp(exp->e_path, path, l) != 0)
+--
+2.0.4
+
diff --git a/main/nfs-utils/0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch b/main/nfs-utils/0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch
deleted file mode 100644
index 263c75102e..0000000000
--- a/main/nfs-utils/0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From c4e7010b9d25b07650ed965243512190f75e8b9c Mon Sep 17 00:00:00 2001
-From: Natanael Copa <ncopa@alpinelinux.org>
-Date: Wed, 12 Feb 2014 14:04:30 +0000
-Subject: [PATCH 6/7] mountd: define _GNU_SOURCE for statfs64 and use standard
- dev_t
-
-Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
----
- utils/mountd/cache.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
-index ca35de2..0a4eba5 100644
---- a/utils/mountd/cache.c
-+++ b/utils/mountd/cache.c
-@@ -11,6 +11,10 @@
- #include <config.h>
- #endif
-
-+#ifndef _GNU_SOURCE
-+#define _GNU_SOURCE
-+#endif
-+
- #include <sys/types.h>
- #include <sys/select.h>
- #include <sys/stat.h>
-@@ -1334,7 +1338,7 @@ static int cache_export_ent(char *domain, struct exportent *exp, char *path)
- */
- struct stat stb;
- size_t l = strlen(exp->e_path);
-- __dev_t dev;
-+ dev_t dev;
-
- if (strlen(path) <= l || path[l] != '/' ||
- strncmp(exp->e_path, path, l) != 0)
---
-1.8.5.3
-
diff --git a/main/nfs-utils/0007-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch b/main/nfs-utils/0006-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
index 09a26b3d09..82477985f3 100644
--- a/main/nfs-utils/0007-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
+++ b/main/nfs-utils/0006-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
@@ -1,7 +1,7 @@
-From e1e75caa7781fc7c8e641516cae214dfe65e6eb6 Mon Sep 17 00:00:00 2001
+From bcf08c3eba0c529077c16110e066750c5cce8292 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 12 Feb 2014 14:07:16 +0000
-Subject: [PATCH 7/7] nfsstat: replace the legacy SA_ONESHOT with standard
+Subject: [PATCH] nfsstat: replace the legacy SA_ONESHOT with standard
SA_RESETHAND
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
@@ -23,5 +23,5 @@ index 70f8d10..3612bfe 100644
if ((progname = strrchr(argv[0], '/')))
--
-1.8.5.3
+2.0.4
diff --git a/main/nfs-utils/0004-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch b/main/nfs-utils/0007-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
index 2544a59646..c39b01fe0a 100644
--- a/main/nfs-utils/0004-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
+++ b/main/nfs-utils/0007-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
@@ -1,19 +1,20 @@
-From c2fc4ac0819b4e6f9591b86245ad537906f9d0cb Mon Sep 17 00:00:00 2001
+From 733d3316dd67aeb175016a098d6d0fd08cefdd33 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 12 Feb 2014 13:54:31 +0000
-Subject: [PATCH 4/7] Allow usage of getrpcbynumber() when getrpcbynumber_r()
- is unavailable
+Subject: [PATCH] Allow usage of getrpcbynumber() when getrpcbynumber_r() is
+ unavailable
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
---
configure.ac | 6 +-----
support/nfs/svc_socket.c | 6 ++++++
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/configure.ac b/configure.ac
-index bf433d6..c758cc7 100644
+index b9682ed..bc48373 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -247,9 +247,6 @@ AC_CHECK_FUNC([connect], ,
+@@ -248,9 +248,6 @@ AC_CHECK_FUNC([connect], ,
AC_CHECK_FUNC([getaddrinfo], ,
[AC_MSG_ERROR([Function 'getaddrinfo' not found.])])
@@ -23,7 +24,7 @@ index bf433d6..c758cc7 100644
AC_CHECK_FUNC([getservbyname], ,
[AC_MSG_ERROR([Function 'getservbyname' not found.])])
-@@ -408,12 +405,11 @@ AC_FUNC_STAT
+@@ -409,12 +406,11 @@ AC_FUNC_STAT
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
gethostbyaddr gethostbyname gethostname getmntent \
@@ -31,7 +32,7 @@ index bf433d6..c758cc7 100644
+ getnameinfo getrpcbyname getrpcbynumber getrpcbynumber_r getifaddrs \
gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
ppoll realpath rmdir select socket strcasecmp strchr strdup \
- strerror strrchr strtol strtoul sigprocmask])
+ strerror strrchr strtol strtoul sigprocmask name_to_handle_at])
-
dnl *************************************************************
@@ -57,5 +58,5 @@ index f56f310..61ccf5b 100644
/* First try name. */
ret = getservbyname_r(rpcp->r_name, proto, &servbuf, servdata,
--
-1.8.5.3
+2.0.4
diff --git a/main/nfs-utils/0001-Only-work-around-glibc-bugs-on-glibc.patch b/main/nfs-utils/0008-Only-work-around-glibc-bugs-on-glibc.patch
index 866173999e..9f87eec597 100644
--- a/main/nfs-utils/0001-Only-work-around-glibc-bugs-on-glibc.patch
+++ b/main/nfs-utils/0008-Only-work-around-glibc-bugs-on-glibc.patch
@@ -1,8 +1,9 @@
-From 94f241e2143090f4ea74b4a68cbb2bec54c5f229 Mon Sep 17 00:00:00 2001
+From 21a0c6b3ace23acd0236339582366bb128065347 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Thu, 24 Apr 2014 14:25:23 +0200
Subject: [PATCH] Only work around glibc bugs on glibc
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
---
utils/mountd/svc_run.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -21,5 +22,5 @@ index 1938a67..a572441 100644
* our own svc_getreqset
*/
--
-1.9.2
+2.0.4
diff --git a/main/nfs-utils/0001-include-libgen.h-for-basename.patch b/main/nfs-utils/0009-include-libgen.h-for-basename.patch
index b10ba929f1..0cca70e1c0 100644
--- a/main/nfs-utils/0001-include-libgen.h-for-basename.patch
+++ b/main/nfs-utils/0009-include-libgen.h-for-basename.patch
@@ -1,4 +1,4 @@
-From 4d3810176cab64e3d748d6cefcea77a258f94c1d Mon Sep 17 00:00:00 2001
+From e828b9c9ac735a18850bd90c61b60064c236937b Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Thu, 24 Apr 2014 10:38:26 +0200
Subject: [PATCH] include libgen.h for basename
@@ -54,7 +54,7 @@ index 701d41e..6f85dc9 100644
#include <libmount/libmount.h>
diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c
-index 73d6a92..b781c20 100644
+index 03e3c81..201bb13 100644
--- a/utils/nfsd/nfsd.c
+++ b/utils/nfsd/nfsd.c
@@ -19,6 +19,7 @@
@@ -78,5 +78,5 @@ index 3f51b4d..e0d31e7 100644
#include <pwd.h>
#include <grp.h>
--
-1.9.2
+2.0.4
diff --git a/main/nfs-utils/0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch b/main/nfs-utils/0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch
new file mode 100644
index 0000000000..00ec08c787
--- /dev/null
+++ b/main/nfs-utils/0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch
@@ -0,0 +1,49 @@
+From 7fc596097b2a0545a8a21e90ecdabdc34073ab49 Mon Sep 17 00:00:00 2001
+From: Natanael Copa <ncopa@alpinelinux.org>
+Date: Mon, 2 Jun 2014 14:20:59 +0200
+Subject: [PATCH] exportfs: fix test of NULL pointer in host_pton()
+
+should fix https://bugzilla.redhat.com/show_bug.cgi?id=1083018
+
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
+---
+ support/export/hostname.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/support/export/hostname.c b/support/export/hostname.c
+index ad595d1..d9153e1 100644
+--- a/support/export/hostname.c
++++ b/support/export/hostname.c
+@@ -115,6 +115,11 @@ host_pton(const char *paddr)
+ * have a real AF_INET presentation address, before invoking
+ * getaddrinfo(3) to generate the full addrinfo list.
+ */
++ if (paddr == NULL) {
++ xlog(D_GENERAL, "%s: passed a NULL presentation address",
++ __func__);
++ return NULL;
++ }
+ inet4 = 1;
+ if (inet_pton(AF_INET, paddr, &sin.sin_addr) == 0)
+ inet4 = 0;
+@@ -123,15 +128,12 @@ host_pton(const char *paddr)
+ switch (error) {
+ case 0:
+ if (!inet4 && ai->ai_addr->sa_family == AF_INET) {
++ xlog(D_GENERAL, "%s: failed to convert %s",
++ __func__, paddr);
+ freeaddrinfo(ai);
+ break;
+ }
+ return ai;
+- case EAI_NONAME:
+- if (paddr == NULL)
+- xlog(D_GENERAL, "%s: passed a NULL presentation address",
+- __func__);
+- break;
+ case EAI_SYSTEM:
+ xlog(D_GENERAL, "%s: failed to convert %s: (%d) %m",
+ __func__, paddr, errno);
+--
+2.0.4
+
diff --git a/main/nfs-utils/0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch b/main/nfs-utils/0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch
new file mode 100644
index 0000000000..607afca289
--- /dev/null
+++ b/main/nfs-utils/0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch
@@ -0,0 +1,39 @@
+From 0b4df13026eb371b68abc4b8cec4ca8d90c3b0a3 Mon Sep 17 00:00:00 2001
+From: Natanael Copa <ncopa@alpinelinux.org>
+Date: Mon, 2 Jun 2014 14:42:10 +0200
+Subject: [PATCH] exportfs: only do glibc specific hackery on glibc
+
+We should not depend on the libc do free(3) on ai_canonname as that is
+completely up to implementation and known o break things on uclibc and
+musl libc.
+
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
+---
+ support/export/hostname.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/support/export/hostname.c b/support/export/hostname.c
+index d9153e1..30584b4 100644
+--- a/support/export/hostname.c
++++ b/support/export/hostname.c
+@@ -382,6 +382,7 @@ host_numeric_addrinfo(const struct sockaddr *sap)
+
+ ai = host_pton(buf);
+
++#if !definded(__UCLIBC__) && defined(__GLIBC__)
+ /*
+ * getaddrinfo(AI_NUMERICHOST) never fills in ai_canonname
+ */
+@@ -392,7 +393,9 @@ host_numeric_addrinfo(const struct sockaddr *sap)
+ ai = NULL;
+ }
+ }
++#endif
+
+ return ai;
+ }
++
+ #endif /* !HAVE_GETNAMEINFO */
+--
+2.0.4
+
diff --git a/main/nfs-utils/0012-rework-access-to-proc-net-rpc.patch b/main/nfs-utils/0012-rework-access-to-proc-net-rpc.patch
new file mode 100644
index 0000000000..e0e4f8651d
--- /dev/null
+++ b/main/nfs-utils/0012-rework-access-to-proc-net-rpc.patch
@@ -0,0 +1,1196 @@
+From 3c74c74244d6b278f94aede59a91e41bf967a2f3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Tue, 5 Aug 2014 16:49:50 +0300
+Subject: [PATCH] rework access to /proc/net/rpc
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The kernel support only access by read() and write() with exactly
+one line in the buffer. FILE can be implemented with readv() and
+writev(), and the mapping to syscalls is not guaranteed. The code
+already does lot of extra work setvbuf() and fflush() calls to try
+to ensure this, but it relays on implementation details and is
+non-portable. And e.g. with musl library the current hacks do not
+work at all.
+
+Remove the FILE based qword_* API as it's fundamentally broken,
+and replace it with explicitly caching one line at a time. The
+qword API should probable improved to do the line caching
+internally, and this is the first step towards that.
+
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+---
+ support/include/exportfs.h | 1 +
+ support/include/nfslib.h | 7 -
+ support/include/nfsrpc.h | 1 +
+ support/nfs/cacheio.c | 111 +-------------
+ support/nfs/nfsexport.c | 77 ++++++----
+ utils/gssd/gssd_proc.c | 9 +-
+ utils/gssd/svcgssd.h | 2 +-
+ utils/gssd/svcgssd_main_loop.c | 9 +-
+ utils/gssd/svcgssd_proc.c | 51 ++++---
+ utils/gssd/write_bytes.h | 1 +
+ utils/mountd/cache.c | 336 ++++++++++++++++++++++-------------------
+ utils/nfsd/nfssvc.c | 1 +
+ 12 files changed, 265 insertions(+), 341 deletions(-)
+
+diff --git a/support/include/exportfs.h b/support/include/exportfs.h
+index 9021fae..32711e4 100644
+--- a/support/include/exportfs.h
++++ b/support/include/exportfs.h
+@@ -10,6 +10,7 @@
+ #define EXPORTFS_H
+
+ #include <netdb.h>
++#include <string.h>
+
+ #include "sockaddr.h"
+ #include "nfslib.h"
+diff --git a/support/include/nfslib.h b/support/include/nfslib.h
+index ce4b14b..9fd22ac 100644
+--- a/support/include/nfslib.h
++++ b/support/include/nfslib.h
+@@ -152,11 +152,6 @@ struct nfs_fh_len * getfh(const struct sockaddr_in *sin, const char *path);
+ struct nfs_fh_len * getfh_size(const struct sockaddr_in *sin,
+ const char *path, int const size);
+
+-void qword_print(FILE *f, char *str);
+-void qword_printhex(FILE *f, char *str, int slen);
+-void qword_printint(FILE *f, int num);
+-int qword_eol(FILE *f);
+-int readline(int fd, char **buf, int *lenp);
+ int qword_get(char **bpp, char *dest, int bufsize);
+ int qword_get_int(char **bpp, int *anint);
+ void cache_flush(int force);
+@@ -167,8 +162,6 @@ void qword_addint(char **bpp, int *lp, int n);
+ void qword_adduint(char **bpp, int *lp, unsigned int n);
+ void qword_addeol(char **bpp, int *lp);
+ int qword_get_uint(char **bpp, unsigned int *anint);
+-void qword_printuint(FILE *f, unsigned int num);
+-void qword_printtimefrom(FILE *f, unsigned int num);
+
+ void closeall(int min);
+
+diff --git a/support/include/nfsrpc.h b/support/include/nfsrpc.h
+index 1bfae7a..fbbdb6a 100644
+--- a/support/include/nfsrpc.h
++++ b/support/include/nfsrpc.h
+@@ -23,6 +23,7 @@
+ #ifndef __NFS_UTILS_NFSRPC_H
+ #define __NFS_UTILS_NFSRPC_H
+
++#include <string.h>
+ #include <rpc/types.h>
+ #include <rpc/clnt.h>
+
+diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c
+index 61e07a8..42e2502 100644
+--- a/support/nfs/cacheio.c
++++ b/support/nfs/cacheio.c
+@@ -18,6 +18,7 @@
+ #include <nfslib.h>
+ #include <stdio.h>
+ #include <stdio_ext.h>
++#include <string.h>
+ #include <ctype.h>
+ #include <unistd.h>
+ #include <sys/types.h>
+@@ -120,74 +121,6 @@ void qword_addeol(char **bpp, int *lp)
+ (*lp)--;
+ }
+
+-static char qword_buf[8192];
+-void qword_print(FILE *f, char *str)
+-{
+- char *bp = qword_buf;
+- int len = sizeof(qword_buf);
+- qword_add(&bp, &len, str);
+- if (fwrite(qword_buf, bp-qword_buf, 1, f) != 1) {
+- xlog_warn("qword_print: fwrite failed: errno %d (%s)",
+- errno, strerror(errno));
+- }
+-}
+-
+-void qword_printhex(FILE *f, char *str, int slen)
+-{
+- char *bp = qword_buf;
+- int len = sizeof(qword_buf);
+- qword_addhex(&bp, &len, str, slen);
+- if (fwrite(qword_buf, bp-qword_buf, 1, f) != 1) {
+- xlog_warn("qword_printhex: fwrite failed: errno %d (%s)",
+- errno, strerror(errno));
+- }
+-}
+-
+-void qword_printint(FILE *f, int num)
+-{
+- fprintf(f, "%d ", num);
+-}
+-
+-void qword_printuint(FILE *f, unsigned int num)
+-{
+- fprintf(f, "%u ", num);
+-}
+-
+-void qword_printtimefrom(FILE *f, unsigned int num)
+-{
+- fprintf(f, "%lu ", time(0) + num);
+-}
+-
+-int qword_eol(FILE *f)
+-{
+- int err;
+-
+- err = fprintf(f,"\n");
+- if (err < 0) {
+- xlog_warn("qword_eol: fprintf failed: errno %d (%s)",
+- errno, strerror(errno));
+- } else {
+- err = fflush(f);
+- if (err) {
+- xlog_warn("qword_eol: fflush failed: errno %d (%s)",
+- errno, strerror(errno));
+- }
+- }
+- /*
+- * We must send one line (and one line only) in a single write
+- * call. In case of a write error, libc may accumulate the
+- * unwritten data and try to write it again later, resulting in a
+- * multi-line write. So we must explicitly ask it to throw away
+- * any such cached data. But we return any original error
+- * indication to the caller.
+- */
+- __fpurge(f);
+- fflush(f);
+- return err;
+-}
+-
+-
+-
+ #define isodigit(c) (isdigit(c) && c <= '7')
+ int qword_get(char **bpp, char *dest, int bufsize)
+ {
+@@ -265,48 +198,6 @@ int qword_get_uint(char **bpp, unsigned int *anint)
+ return 0;
+ }
+
+-#define READLINE_BUFFER_INCREMENT 2048
+-
+-int readline(int fd, char **buf, int *lenp)
+-{
+- /* read a line into *buf, which is malloced *len long
+- * realloc if needed until we find a \n
+- * nul out the \n and return
+- * 0 on eof, 1 on success
+- */
+- int len;
+-
+- if (*lenp == 0) {
+- char *b = malloc(READLINE_BUFFER_INCREMENT);
+- if (b == NULL)
+- return 0;
+- *buf = b;
+- *lenp = READLINE_BUFFER_INCREMENT;
+- }
+- len = read(fd, *buf, *lenp);
+- if (len <= 0)
+- return 0;
+- while ((*buf)[len-1] != '\n') {
+- /* now the less common case. There was no newline,
+- * so we have to keep reading after re-alloc
+- */
+- char *new;
+- int nl;
+- *lenp += READLINE_BUFFER_INCREMENT;
+- new = realloc(*buf, *lenp);
+- if (new == NULL)
+- return 0;
+- *buf = new;
+- nl = read(fd, *buf + len, *lenp - len);
+- if (nl <= 0)
+- return 0;
+- len += nl;
+- }
+- (*buf)[len-1] = '\0';
+- return 1;
+-}
+-
+-
+ /* Check if we should use the new caching interface
+ * This succeeds iff the "nfsd" filesystem is mounted on
+ * /proc/fs/nfs
+diff --git a/support/nfs/nfsexport.c b/support/nfs/nfsexport.c
+index f129fd2..afd7c90 100644
+--- a/support/nfs/nfsexport.c
++++ b/support/nfs/nfsexport.c
+@@ -18,6 +18,7 @@
+ #include <fcntl.h>
+
+ #include "nfslib.h"
++#include "misc.h"
+
+ /* if /proc/net/rpc/... exists, then
+ * write to it, as that interface is more stable.
+@@ -32,62 +33,72 @@
+ static int
+ exp_unexp(struct nfsctl_export *exp, int export)
+ {
+- FILE *f;
++ char buf[RPC_CHAN_BUF_SIZE], *bp;
+ struct stat stb;
+ __u32 fsid;
+ char fsidstr[8];
+ __u16 dev;
+ __u32 inode;
+- int err;
++ int err = 0, f, blen;
+
++ f = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY);
++ if (f < 0) return -1;
+
+- f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
+- if (f == NULL) return -1;
+- qword_print(f, exp->ex_client);
+- qword_print(f, exp->ex_path);
++ bp = buf; blen = sizeof(buf);
++ qword_add(&bp, &blen, exp->ex_client);
++ qword_add(&bp, &blen, exp->ex_path);
+ if (export) {
+- qword_printint(f, 0x7fffffff);
+- qword_printint(f, exp->ex_flags);
+- qword_printint(f, exp->ex_anon_uid);
+- qword_printint(f, exp->ex_anon_gid);
+- qword_printint(f, exp->ex_dev);
++ qword_addint(&bp, &blen, 0x7fffffff);
++ qword_addint(&bp, &blen, exp->ex_flags);
++ qword_addint(&bp, &blen, exp->ex_anon_uid);
++ qword_addint(&bp, &blen, exp->ex_anon_gid);
++ qword_addint(&bp, &blen, exp->ex_dev);
+ } else
+- qword_printint(f, 1);
+-
+- err = qword_eol(f);
+- fclose(f);
++ qword_addint(&bp, &blen, 1);
++ qword_addeol(&bp, &blen);
++ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
++ err = -1;
++ close(f);
+
+ if (stat(exp->ex_path, &stb) != 0)
+ return -1;
+- f = fopen("/proc/net/rpc/nfsd.fh/channel", "w");
+- if (f==NULL) return -1;
++
++ f = open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY);
++ if (f < 0) return -1;
+ if (exp->ex_flags & NFSEXP_FSID) {
+- qword_print(f,exp->ex_client);
+- qword_printint(f,1);
++ bp = buf; blen = sizeof(buf);
++ qword_add(&bp, &blen, exp->ex_client);
++ qword_addint(&bp, &blen, 1);
+ fsid = exp->ex_dev;
+- qword_printhex(f, (char*)&fsid, 4);
++ qword_addhex(&bp, &blen, (char*)&fsid, 4);
+ if (export) {
+- qword_printint(f, 0x7fffffff);
+- qword_print(f, exp->ex_path);
++ qword_addint(&bp, &blen, 0x7fffffff);
++ qword_add(&bp, &blen, exp->ex_path);
+ } else
+- qword_printint(f, 1);
+-
+- err = qword_eol(f) || err;
++ qword_addint(&bp, &blen, 1);
++ qword_addeol(&bp, &blen);
++ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
++ err = -1;
+ }
+- qword_print(f,exp->ex_client);
+- qword_printint(f,0);
++
++ bp = buf; blen = sizeof(buf);
++ qword_add(&bp, &blen, exp->ex_client);
++ qword_addint(&bp, &blen, 0);
+ dev = htons(major(stb.st_dev)); memcpy(fsidstr, &dev, 2);
+ dev = htons(minor(stb.st_dev)); memcpy(fsidstr+2, &dev, 2);
+ inode = stb.st_ino; memcpy(fsidstr+4, &inode, 4);
+
+- qword_printhex(f, fsidstr, 8);
++ qword_addhex(&bp, &blen, fsidstr, 8);
+ if (export) {
+- qword_printint(f, 0x7fffffff);
+- qword_print(f, exp->ex_path);
++ qword_addint(&bp, &blen, 0x7fffffff);
++ qword_add(&bp, &blen, exp->ex_path);
+ } else
+- qword_printint(f, 1);
+- err = qword_eol(f) || err;
+- fclose(f);
++ qword_addint(&bp, &blen, 1);
++ qword_addeol(&bp, &blen);
++ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
++ err = -1;
++ close(f);
++
+ return err;
+ }
+
+diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
+index 121feb1..1d8e6a7 100644
+--- a/utils/gssd/gssd_proc.c
++++ b/utils/gssd/gssd_proc.c
+@@ -78,6 +78,7 @@
+ #include "nfsrpc.h"
+ #include "nfslib.h"
+ #include "gss_names.h"
++#include "misc.h"
+
+ /*
+ * pollarray:
+@@ -1250,7 +1251,7 @@ void
+ handle_gssd_upcall(struct clnt_info *clp)
+ {
+ uid_t uid;
+- char *lbuf = NULL;
++ char lbuf[RPC_CHAN_BUF_SIZE];
+ int lbuflen = 0;
+ char *p;
+ char *mech = NULL;
+@@ -1260,11 +1261,14 @@ handle_gssd_upcall(struct clnt_info *clp)
+
+ printerr(1, "handling gssd upcall (%s)\n", clp->dirname);
+
+- if (readline(clp->gssd_fd, &lbuf, &lbuflen) != 1) {
++ lbuflen = read(clp->gssd_fd, lbuf, sizeof(lbuf));
++ if (lbuflen <= 0 || lbuf[lbuflen-1] != '\n') {
+ printerr(0, "WARNING: handle_gssd_upcall: "
+ "failed reading request\n");
+ return;
+ }
++ lbuf[lbuflen-1] = 0;
++
+ printerr(2, "%s: '%s'\n", __func__, lbuf);
+
+ /* find the mechanism name */
+@@ -1362,7 +1366,6 @@ handle_gssd_upcall(struct clnt_info *clp)
+ }
+
+ out:
+- free(lbuf);
+ free(mech);
+ free(enctypes);
+ free(target);
+diff --git a/utils/gssd/svcgssd.h b/utils/gssd/svcgssd.h
+index 9a2e2e8..02b5c7a 100644
+--- a/utils/gssd/svcgssd.h
++++ b/utils/gssd/svcgssd.h
+@@ -35,7 +35,7 @@
+ #include <sys/queue.h>
+ #include <gssapi/gssapi.h>
+
+-void handle_nullreq(FILE *f);
++void handle_nullreq(int f);
+ void gssd_run(void);
+
+ #define GSSD_SERVICE_NAME "nfs"
+diff --git a/utils/gssd/svcgssd_main_loop.c b/utils/gssd/svcgssd_main_loop.c
+index 2b4111c..b5681ce 100644
+--- a/utils/gssd/svcgssd_main_loop.c
++++ b/utils/gssd/svcgssd_main_loop.c
+@@ -54,19 +54,18 @@ void
+ gssd_run()
+ {
+ int ret;
+- FILE *f;
++ int f;
+ struct pollfd pollfd;
+
+ #define NULLRPC_FILE "/proc/net/rpc/auth.rpcsec.init/channel"
+
+- f = fopen(NULLRPC_FILE, "rw");
+-
+- if (!f) {
++ f = open(NULLRPC_FILE, O_RDWR);
++ if (f < 0) {
+ printerr(0, "failed to open %s: %s\n",
+ NULLRPC_FILE, strerror(errno));
+ exit(1);
+ }
+- pollfd.fd = fileno(f);
++ pollfd.fd = f;
+ pollfd.events = POLLIN;
+ while (1) {
+ int save_err;
+diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c
+index 5bdb438..72ec254 100644
+--- a/utils/gssd/svcgssd_proc.c
++++ b/utils/gssd/svcgssd_proc.c
+@@ -73,36 +73,35 @@ struct svc_cred {
+ int cr_ngroups;
+ gid_t cr_groups[NGROUPS];
+ };
+-static char vbuf[RPC_CHAN_BUF_SIZE];
+
+ static int
+ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
+ gss_OID mech, gss_buffer_desc *context_token,
+ int32_t endtime, char *client_name)
+ {
+- FILE *f;
+- int i;
++ char buf[RPC_CHAN_BUF_SIZE], *bp;
++ int i, f, err, blen;
+ char *fname = NULL;
+- int err;
+
+ printerr(1, "doing downcall\n");
+ if ((fname = mech2file(mech)) == NULL)
+ goto out_err;
+- f = fopen(SVCGSSD_CONTEXT_CHANNEL, "w");
+- if (f == NULL) {
++
++ f = open(SVCGSSD_CONTEXT_CHANNEL, O_WRONLY);
++ if (f < 0) {
+ printerr(0, "WARNING: unable to open downcall channel "
+ "%s: %s\n",
+ SVCGSSD_CONTEXT_CHANNEL, strerror(errno));
+ goto out_err;
+ }
+- setvbuf(f, vbuf, _IOLBF, RPC_CHAN_BUF_SIZE);
+- qword_printhex(f, out_handle->value, out_handle->length);
++ bp = buf, blen = sizeof(buf);
++ qword_addhex(&bp, &blen, out_handle->value, out_handle->length);
+ /* XXX are types OK for the rest of this? */
+ /* For context cache, use the actual context endtime */
+- qword_printint(f, endtime);
+- qword_printint(f, cred->cr_uid);
+- qword_printint(f, cred->cr_gid);
+- qword_printint(f, cred->cr_ngroups);
++ qword_addint(&bp, &blen, endtime);
++ qword_addint(&bp, &blen, cred->cr_uid);
++ qword_addint(&bp, &blen, cred->cr_gid);
++ qword_addint(&bp, &blen, cred->cr_ngroups);
+ printerr(2, "mech: %s, hndl len: %d, ctx len %d, timeout: %d (%d from now), "
+ "clnt: %s, uid: %d, gid: %d, num aux grps: %d:\n",
+ fname, out_handle->length, context_token->length,
+@@ -110,19 +109,21 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
+ client_name ? client_name : "<null>",
+ cred->cr_uid, cred->cr_gid, cred->cr_ngroups);
+ for (i=0; i < cred->cr_ngroups; i++) {
+- qword_printint(f, cred->cr_groups[i]);
++ qword_addint(&bp, &blen, cred->cr_groups[i]);
+ printerr(2, " (%4d) %d\n", i+1, cred->cr_groups[i]);
+ }
+- qword_print(f, fname);
+- qword_printhex(f, context_token->value, context_token->length);
++ qword_add(&bp, &blen, fname);
++ qword_addhex(&bp, &blen, context_token->value, context_token->length);
+ if (client_name)
+- qword_print(f, client_name);
+- err = qword_eol(f);
+- if (err) {
++ qword_add(&bp, &blen, client_name);
++ qword_addeol(&bp, &blen);
++ err = 0;
++ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) {
+ printerr(1, "WARNING: error writing to downcall channel "
+ "%s: %s\n", SVCGSSD_CONTEXT_CHANNEL, strerror(errno));
++ err = -1;
+ }
+- fclose(f);
++ close(f);
+ return err;
+ out_err:
+ printerr(1, "WARNING: downcall failed\n");
+@@ -317,7 +318,7 @@ print_hexl(const char *description, unsigned char *cp, int length)
+ #endif
+
+ void
+-handle_nullreq(FILE *f) {
++handle_nullreq(int f) {
+ /* XXX initialize to a random integer to reduce chances of unnecessary
+ * invalidation of existing ctx's on restarting svcgssd. */
+ static u_int32_t handle_seq = 0;
+@@ -339,19 +340,21 @@ handle_nullreq(FILE *f) {
+ u_int32_t maj_stat = GSS_S_FAILURE, min_stat = 0;
+ u_int32_t ignore_min_stat;
+ struct svc_cred cred;
+- static char *lbuf = NULL;
+- static int lbuflen = 0;
+- static char *cp;
++ char lbuf[RPC_CHAN_BUF_SIZE];
++ int lbuflen = 0;
++ char *cp;
+ int32_t ctx_endtime;
+ char *hostbased_name = NULL;
+
+ printerr(1, "handling null request\n");
+
+- if (readline(fileno(f), &lbuf, &lbuflen) != 1) {
++ lbuflen = read(f, lbuf, sizeof(lbuf));
++ if (lbuflen <= 0 || lbuf[lbuflen-1] != '\n') {
+ printerr(0, "WARNING: handle_nullreq: "
+ "failed reading request\n");
+ return;
+ }
++ lbuf[lbuflen-1] = 0;
+
+ cp = lbuf;
+
+diff --git a/utils/gssd/write_bytes.h b/utils/gssd/write_bytes.h
+index 4fc72cc..b3f342b 100644
+--- a/utils/gssd/write_bytes.h
++++ b/utils/gssd/write_bytes.h
+@@ -32,6 +32,7 @@
+ #define _WRITE_BYTES_H_
+
+ #include <stdlib.h>
++#include <string.h>
+ #include <sys/types.h>
+ #include <netinet/in.h> /* for ntohl */
+
+diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
+index 663a52a..465ce65 100644
+--- a/utils/mountd/cache.c
++++ b/utils/mountd/cache.c
+@@ -61,15 +61,13 @@ enum nfsd_fsid {
+ * Record is terminated with newline.
+ *
+ */
+-static int cache_export_ent(char *domain, struct exportent *exp, char *p);
++static int cache_export_ent(char *buf, int buflen, char *domain, struct exportent *exp, char *path);
+
+ #define INITIAL_MANAGED_GROUPS 100
+
+-char *lbuf = NULL;
+-int lbuflen = 0;
+ extern int use_ipaddr;
+
+-static void auth_unix_ip(FILE *f)
++static void auth_unix_ip(int f)
+ {
+ /* requests are
+ * class IP-ADDR
+@@ -78,23 +76,26 @@ static void auth_unix_ip(FILE *f)
+ *
+ * "nfsd" IP-ADDR expiry domainname
+ */
+- char *cp;
+ char class[20];
+ char ipaddr[INET6_ADDRSTRLEN + 1];
+ char *client = NULL;
+ struct addrinfo *tmp = NULL;
+- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
+- return;
++ char buf[RPC_CHAN_BUF_SIZE], *bp;
++ int blen;
++
++ blen = read(f, buf, sizeof(buf));
++ if (blen <= 0 || buf[blen-1] != '\n') return;
++ buf[blen-1] = 0;
+
+- xlog(D_CALL, "auth_unix_ip: inbuf '%s'", lbuf);
++ xlog(D_CALL, "auth_unix_ip: inbuf '%s'", buf);
+
+- cp = lbuf;
++ bp = buf;
+
+- if (qword_get(&cp, class, 20) <= 0 ||
++ if (qword_get(&bp, class, 20) <= 0 ||
+ strcmp(class, "nfsd") != 0)
+ return;
+
+- if (qword_get(&cp, ipaddr, sizeof(ipaddr) - 1) <= 0)
++ if (qword_get(&bp, ipaddr, sizeof(ipaddr) - 1) <= 0)
+ return;
+
+ tmp = host_pton(ipaddr);
+@@ -113,16 +114,19 @@ static void auth_unix_ip(FILE *f)
+ freeaddrinfo(ai);
+ }
+ }
+- qword_print(f, "nfsd");
+- qword_print(f, ipaddr);
+- qword_printtimefrom(f, DEFAULT_TTL);
++ bp = buf; blen = sizeof(buf);
++ qword_add(&bp, &blen, "nfsd");
++ qword_add(&bp, &blen, ipaddr);
++ qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL);
+ if (use_ipaddr) {
+ memmove(ipaddr + 1, ipaddr, strlen(ipaddr) + 1);
+ ipaddr[0] = '$';
+- qword_print(f, ipaddr);
++ qword_add(&bp, &blen, ipaddr);
+ } else if (client)
+- qword_print(f, *client?client:"DEFAULT");
+- qword_eol(f);
++ qword_add(&bp, &blen, *client?client:"DEFAULT");
++ qword_addeol(&bp, &blen);
++ if (blen > 0) write(f, buf, bp - buf);
++
+ xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT");
+
+ free(client);
+@@ -130,7 +134,7 @@ static void auth_unix_ip(FILE *f)
+
+ }
+
+-static void auth_unix_gid(FILE *f)
++static void auth_unix_gid(int f)
+ {
+ /* Request are
+ * uid
+@@ -144,7 +148,8 @@ static void auth_unix_gid(FILE *f)
+ gid_t *more_groups;
+ int ngroups;
+ int rv, i;
+- char *cp;
++ char buf[RPC_CHAN_BUF_SIZE], *bp;
++ int blen;
+
+ if (groups_len == 0) {
+ groups = malloc(sizeof(gid_t) * INITIAL_MANAGED_GROUPS);
+@@ -156,11 +161,12 @@ static void auth_unix_gid(FILE *f)
+
+ ngroups = groups_len;
+
+- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
+- return;
++ blen = read(f, buf, sizeof(buf));
++ if (blen <= 0 || buf[blen-1] != '\n') return;
++ buf[blen-1] = 0;
+
+- cp = lbuf;
+- if (qword_get_uint(&cp, &uid) != 0)
++ bp = buf;
++ if (qword_get_uint(&bp, &uid) != 0)
+ return;
+
+ pw = getpwuid(uid);
+@@ -180,15 +186,18 @@ static void auth_unix_gid(FILE *f)
+ }
+ }
+ }
+- qword_printuint(f, uid);
+- qword_printtimefrom(f, DEFAULT_TTL);
++
++ bp = buf; blen = sizeof(buf);
++ qword_adduint(&bp, &blen, uid);
++ qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL);
+ if (rv >= 0) {
+- qword_printuint(f, ngroups);
++ qword_adduint(&bp, &blen, ngroups);
+ for (i=0; i<ngroups; i++)
+- qword_printuint(f, groups[i]);
++ qword_adduint(&bp, &blen, groups[i]);
+ } else
+- qword_printuint(f, 0);
+- qword_eol(f);
++ qword_adduint(&bp, &blen, 0);
++ qword_addeol(&bp, &blen);
++ if (blen > 0) write(f, buf, bp - buf);
+ }
+
+ #if USE_BLKID
+@@ -659,14 +668,13 @@ static struct addrinfo *lookup_client_addr(char *dom)
+ return ret;
+ }
+
+-static void nfsd_fh(FILE *f)
++static void nfsd_fh(int f)
+ {
+ /* request are:
+ * domain fsidtype fsid
+ * interpret fsid, find export point and options, and write:
+ * domain fsidtype fsid expiry path
+ */
+- char *cp;
+ char *dom;
+ int fsidtype;
+ int fsidlen;
+@@ -678,24 +686,27 @@ static void nfsd_fh(FILE *f)
+ nfs_export *exp;
+ int i;
+ int dev_missing = 0;
++ char buf[RPC_CHAN_BUF_SIZE], *bp;
++ int blen;
+
+- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
+- return;
++ blen = read(f, buf, sizeof(buf));
++ if (blen <= 0 || buf[blen-1] != '\n') return;
++ buf[blen-1] = 0;
+
+- xlog(D_CALL, "nfsd_fh: inbuf '%s'", lbuf);
++ xlog(D_CALL, "nfsd_fh: inbuf '%s'", buf);
+
+- cp = lbuf;
++ bp = buf;
+
+- dom = malloc(strlen(cp));
++ dom = malloc(blen);
+ if (dom == NULL)
+ return;
+- if (qword_get(&cp, dom, strlen(cp)) <= 0)
++ if (qword_get(&bp, dom, blen) <= 0)
+ goto out;
+- if (qword_get_int(&cp, &fsidtype) != 0)
++ if (qword_get_int(&bp, &fsidtype) != 0)
+ goto out;
+ if (fsidtype < 0 || fsidtype > 7)
+ goto out; /* unknown type */
+- if ((fsidlen = qword_get(&cp, fsid, 32)) <= 0)
++ if ((fsidlen = qword_get(&bp, fsid, 32)) <= 0)
+ goto out;
+ if (parse_fsid(fsidtype, fsidlen, fsid, &parsed))
+ goto out;
+@@ -796,12 +807,13 @@ static void nfsd_fh(FILE *f)
+ }
+
+ if (found)
+- if (cache_export_ent(dom, found, found_path) < 0)
++ if (cache_export_ent(buf, sizeof(buf), dom, found, found_path) < 0)
+ found = 0;
+
+- qword_print(f, dom);
+- qword_printint(f, fsidtype);
+- qword_printhex(f, fsid, fsidlen);
++ bp = buf; blen = sizeof(buf);
++ qword_add(&bp, &blen, dom);
++ qword_addint(&bp, &blen, fsidtype);
++ qword_addhex(&bp, &blen, fsid, fsidlen);
+ /* The fsid -> path lookup can be quite expensive as it
+ * potentially stats and reads lots of devices, and some of those
+ * might have spun-down. The Answer is not likely to
+@@ -810,10 +822,11 @@ static void nfsd_fh(FILE *f)
+ * timeout. Maybe this should be configurable on the command
+ * line.
+ */
+- qword_printint(f, 0x7fffffff);
++ qword_addint(&bp, &blen, 0x7fffffff);
+ if (found)
+- qword_print(f, found_path);
+- qword_eol(f);
++ qword_add(&bp, &blen, found_path);
++ qword_addeol(&bp, &blen);
++ if (blen > 0) write(f, buf, bp - buf);
+ out:
+ if (found_path)
+ free(found_path);
+@@ -823,7 +836,7 @@ static void nfsd_fh(FILE *f)
+ return;
+ }
+
+-static void write_fsloc(FILE *f, struct exportent *ep)
++static void write_fsloc(char **bp, int *blen, struct exportent *ep)
+ {
+ struct servers *servers;
+
+@@ -833,20 +846,20 @@ static void write_fsloc(FILE *f, struct exportent *ep)
+ servers = replicas_lookup(ep->e_fslocmethod, ep->e_fslocdata);
+ if (!servers)
+ return;
+- qword_print(f, "fsloc");
+- qword_printint(f, servers->h_num);
++ qword_add(bp, blen, "fsloc");
++ qword_addint(bp, blen, servers->h_num);
+ if (servers->h_num >= 0) {
+ int i;
+ for (i=0; i<servers->h_num; i++) {
+- qword_print(f, servers->h_mp[i]->h_host);
+- qword_print(f, servers->h_mp[i]->h_path);
++ qword_add(bp, blen, servers->h_mp[i]->h_host);
++ qword_add(bp, blen, servers->h_mp[i]->h_path);
+ }
+ }
+- qword_printint(f, servers->h_referral);
++ qword_addint(bp, blen, servers->h_referral);
+ release_replicas(servers);
+ }
+
+-static void write_secinfo(FILE *f, struct exportent *ep, int flag_mask)
++static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask)
+ {
+ struct sec_entry *p;
+
+@@ -857,45 +870,51 @@ static void write_secinfo(FILE *f, struct exportent *ep, int flag_mask)
+ return;
+ }
+ fix_pseudoflavor_flags(ep);
+- qword_print(f, "secinfo");
+- qword_printint(f, p - ep->e_secinfo);
++ qword_add(bp, blen, "secinfo");
++ qword_addint(bp, blen, p - ep->e_secinfo);
+ for (p = ep->e_secinfo; p->flav; p++) {
+- qword_printint(f, p->flav->fnum);
+- qword_printint(f, p->flags & flag_mask);
++ qword_addint(bp, blen, p->flav->fnum);
++ qword_addint(bp, blen, p->flags & flag_mask);
+ }
+
+ }
+
+-static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp)
++static int dump_to_cache(int f, char *buf, int buflen, char *domain, char *path, struct exportent *exp)
+ {
+- qword_print(f, domain);
+- qword_print(f, path);
++ char *bp = buf;
++ int blen = buflen;
++
++ qword_add(&bp, &blen, domain);
++ qword_add(&bp, &blen, path);
+ if (exp) {
+ int different_fs = strcmp(path, exp->e_path) != 0;
+ int flag_mask = different_fs ? ~NFSEXP_FSID : ~0;
+
+- qword_printtimefrom(f, exp->e_ttl);
+- qword_printint(f, exp->e_flags & flag_mask);
+- qword_printint(f, exp->e_anonuid);
+- qword_printint(f, exp->e_anongid);
+- qword_printint(f, exp->e_fsid);
+- write_fsloc(f, exp);
+- write_secinfo(f, exp, flag_mask);
+- if (exp->e_uuid == NULL || different_fs) {
+- char u[16];
+- if (uuid_by_path(path, 0, 16, u)) {
+- qword_print(f, "uuid");
+- qword_printhex(f, u, 16);
+- }
+- } else {
+- char u[16];
+- get_uuid(exp->e_uuid, 16, u);
+- qword_print(f, "uuid");
+- qword_printhex(f, u, 16);
+- }
++ qword_adduint(&bp, &blen, time(0) + exp->e_ttl);
++ qword_addint(&bp, &blen, exp->e_flags & flag_mask);
++ qword_addint(&bp, &blen, exp->e_anonuid);
++ qword_addint(&bp, &blen, exp->e_anongid);
++ qword_addint(&bp, &blen, exp->e_fsid);
++ write_fsloc(&bp, &blen, exp);
++ write_secinfo(&bp, &blen, exp, flag_mask);
++ if (exp->e_uuid == NULL || different_fs) {
++ char u[16];
++ if (uuid_by_path(path, 0, 16, u)) {
++ qword_add(&bp, &blen, "uuid");
++ qword_addhex(&bp, &blen, u, 16);
++ }
++ } else {
++ char u[16];
++ get_uuid(exp->e_uuid, 16, u);
++ qword_add(&bp, &blen, "uuid");
++ qword_addhex(&bp, &blen, u, 16);
++ }
+ } else
+- qword_printtimefrom(f, DEFAULT_TTL);
+- return qword_eol(f);
++ qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL);
++ qword_addeol(&bp, &blen);
++ if (blen <= 0) return -1;
++ if (write(f, buf, bp - buf) != bp - buf) return -1;
++ return 0;
+ }
+
+ static nfs_export *
+@@ -1245,27 +1264,27 @@ static struct exportent *lookup_junction(char *dom, const char *pathname,
+ return exp;
+ }
+
+-static void lookup_nonexport(FILE *f, char *dom, char *path,
++static void lookup_nonexport(int f, char *buf, int buflen, char *dom, char *path,
+ struct addrinfo *ai)
+ {
+ struct exportent *eep;
+
+ eep = lookup_junction(dom, path, ai);
+- dump_to_cache(f, dom, path, eep);
++ dump_to_cache(f, buf, buflen, dom, path, eep);
+ if (eep == NULL)
+ return;
+ exportent_release(eep);
+ free(eep);
+ }
+ #else /* !HAVE_NFS_PLUGIN_H */
+-static void lookup_nonexport(FILE *f, char *dom, char *path,
++static void lookup_nonexport(int f, char *buf, int buflen, char *dom, char *path,
+ struct addrinfo *UNUSED(ai))
+ {
+- dump_to_cache(f, dom, path, NULL);
++ dump_to_cache(f, buf, buflen, dom, path, NULL);
+ }
+ #endif /* !HAVE_NFS_PLUGIN_H */
+
+-static void nfsd_export(FILE *f)
++static void nfsd_export(int f)
+ {
+ /* requests are:
+ * domain path
+@@ -1273,26 +1292,28 @@ static void nfsd_export(FILE *f)
+ * domain path expiry flags anonuid anongid fsid
+ */
+
+- char *cp;
+ char *dom, *path;
+ nfs_export *found = NULL;
+ struct addrinfo *ai = NULL;
++ char buf[RPC_CHAN_BUF_SIZE], *bp;
++ int blen;
+
+- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
+- return;
++ blen = read(f, buf, sizeof(buf));
++ if (blen <= 0 || buf[blen-1] != '\n') return;
++ buf[blen-1] = 0;
+
+- xlog(D_CALL, "nfsd_export: inbuf '%s'", lbuf);
++ xlog(D_CALL, "nfsd_export: inbuf '%s'", buf);
+
+- cp = lbuf;
+- dom = malloc(strlen(cp));
+- path = malloc(strlen(cp));
++ bp = buf;
++ dom = malloc(blen);
++ path = malloc(blen);
+
+ if (!dom || !path)
+ goto out;
+
+- if (qword_get(&cp, dom, strlen(lbuf)) <= 0)
++ if (qword_get(&bp, dom, blen) <= 0)
+ goto out;
+- if (qword_get(&cp, path, strlen(lbuf)) <= 0)
++ if (qword_get(&bp, path, blen) <= 0)
+ goto out;
+
+ auth_reload();
+@@ -1306,14 +1327,14 @@ static void nfsd_export(FILE *f)
+ found = lookup_export(dom, path, ai);
+
+ if (found) {
+- if (dump_to_cache(f, dom, path, &found->m_export) < 0) {
++ if (dump_to_cache(f, buf, sizeof(buf), dom, path, &found->m_export) < 0) {
+ xlog(L_WARNING,
+ "Cannot export %s, possibly unsupported filesystem"
+ " or fsid= required", path);
+- dump_to_cache(f, dom, path, NULL);
++ dump_to_cache(f, buf, sizeof(buf), dom, path, NULL);
+ }
+ } else
+- lookup_nonexport(f, dom, path, ai);
++ lookup_nonexport(f, buf, sizeof(buf), dom, path, ai);
+
+ out:
+ xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
+@@ -1325,15 +1346,14 @@ static void nfsd_export(FILE *f)
+
+ struct {
+ char *cache_name;
+- void (*cache_handle)(FILE *f);
+- FILE *f;
+- char vbuf[RPC_CHAN_BUF_SIZE];
++ void (*cache_handle)(int f);
++ int f;
+ } cachelist[] = {
+- { "auth.unix.ip", auth_unix_ip, NULL, ""},
+- { "auth.unix.gid", auth_unix_gid, NULL, ""},
+- { "nfsd.export", nfsd_export, NULL, ""},
+- { "nfsd.fh", nfsd_fh, NULL, ""},
+- { NULL, NULL, NULL, ""}
++ { "auth.unix.ip", auth_unix_ip, -1 },
++ { "auth.unix.gid", auth_unix_gid, -1 },
++ { "nfsd.export", nfsd_export, -1 },
++ { "nfsd.fh", nfsd_fh, -1 },
++ { NULL, NULL, -1 }
+ };
+
+ extern int manage_gids;
+@@ -1350,11 +1370,7 @@ void cache_open(void)
+ if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid)
+ continue;
+ sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
+- cachelist[i].f = fopen(path, "r+");
+- if (cachelist[i].f != NULL) {
+- setvbuf(cachelist[i].f, cachelist[i].vbuf, _IOLBF,
+- RPC_CHAN_BUF_SIZE);
+- }
++ cachelist[i].f = open(path, O_RDWR);
+ }
+ }
+
+@@ -1366,8 +1382,8 @@ void cache_set_fds(fd_set *fdset)
+ {
+ int i;
+ for (i=0; cachelist[i].cache_name; i++) {
+- if (cachelist[i].f)
+- FD_SET(fileno(cachelist[i].f), fdset);
++ if (cachelist[i].f >= 0)
++ FD_SET(cachelist[i].f, fdset);
+ }
+ }
+
+@@ -1380,11 +1396,11 @@ int cache_process_req(fd_set *readfds)
+ int i;
+ int cnt = 0;
+ for (i=0; cachelist[i].cache_name; i++) {
+- if (cachelist[i].f != NULL &&
+- FD_ISSET(fileno(cachelist[i].f), readfds)) {
++ if (cachelist[i].f >= 0 &&
++ FD_ISSET(cachelist[i].f, readfds)) {
+ cnt++;
+ cachelist[i].cache_handle(cachelist[i].f);
+- FD_CLR(fileno(cachelist[i].f), readfds);
++ FD_CLR(cachelist[i].f, readfds);
+ }
+ }
+ return cnt;
+@@ -1397,14 +1413,14 @@ int cache_process_req(fd_set *readfds)
+ * % echo $domain $path $[now+DEFAULT_TTL] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel
+ */
+
+-static int cache_export_ent(char *domain, struct exportent *exp, char *path)
++static int cache_export_ent(char *buf, int buflen, char *domain, struct exportent *exp, char *path)
+ {
+- int err;
+- FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
+- if (!f)
+- return -1;
++ int f, err;
++
++ f = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY);
++ if (f < 0) return -1;
+
+- err = dump_to_cache(f, domain, exp->e_path, exp);
++ err = dump_to_cache(f, buf, buflen, domain, exp->e_path, exp);
+ if (err) {
+ xlog(L_WARNING,
+ "Cannot export %s, possibly unsupported filesystem or"
+@@ -1445,13 +1461,13 @@ static int cache_export_ent(char *domain, struct exportent *exp, char *path)
+ continue;
+ dev = stb.st_dev;
+ path[l] = 0;
+- dump_to_cache(f, domain, path, exp);
++ dump_to_cache(f, buf, buflen, domain, path, exp);
+ path[l] = c;
+ }
+ break;
+ }
+
+- fclose(f);
++ close(f);
+ return err;
+ }
+
+@@ -1462,27 +1478,25 @@ static int cache_export_ent(char *domain, struct exportent *exp, char *path)
+ */
+ int cache_export(nfs_export *exp, char *path)
+ {
+- char buf[INET6_ADDRSTRLEN];
+- int err;
+- FILE *f;
++ char ip[INET6_ADDRSTRLEN];
++ char buf[RPC_CHAN_BUF_SIZE], *bp;
++ int blen, f;
+
+- f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w");
+- if (!f)
++ f = open("/proc/net/rpc/auth.unix.ip/channel", O_WRONLY);
++ if (f < 0)
+ return -1;
+
+-
+- qword_print(f, "nfsd");
+- qword_print(f,
+- host_ntop(get_addrlist(exp->m_client, 0), buf, sizeof(buf)));
+- qword_printtimefrom(f, exp->m_export.e_ttl);
+- qword_print(f, exp->m_client->m_hostname);
+- err = qword_eol(f);
+-
+- fclose(f);
+-
+- err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export, path)
+- || err;
+- return err;
++ bp = buf, blen = sizeof(buf);
++ qword_add(&bp, &blen, "nfsd");
++ qword_add(&bp, &blen, host_ntop(get_addrlist(exp->m_client, 0), ip, sizeof(ip)));
++ qword_adduint(&bp, &blen, time(0) + exp->m_export.e_ttl);
++ qword_add(&bp, &blen, exp->m_client->m_hostname);
++ qword_addeol(&bp, &blen);
++ if (blen > 0) write(f, buf, bp - buf);
++ close(f);
++ if (blen <= 0) return -1;
++
++ return cache_export_ent(buf, sizeof(buf), exp->m_client->m_hostname, &exp->m_export, path);
+ }
+
+ /**
+@@ -1501,28 +1515,34 @@ int cache_export(nfs_export *exp, char *path)
+ struct nfs_fh_len *
+ cache_get_filehandle(nfs_export *exp, int len, char *p)
+ {
+- FILE *f = fopen("/proc/fs/nfsd/filehandle", "r+");
+- char buf[200];
+- char *bp = buf;
+- int failed;
+ static struct nfs_fh_len fh;
++ char buf[200], *bp;
++ int blen, f;
++
++ f = open("/proc/fs/nfsd/filehandle", O_RDWR);
++ if (f < 0) {
++ f = open("/proc/fs/nfs/filehandle", O_RDWR);
++ if (f < 0) return NULL;
++ }
+
+- if (!f)
+- f = fopen("/proc/fs/nfs/filehandle", "r+");
+- if (!f)
++ bp = buf, blen = sizeof(buf);
++ qword_add(&bp, &blen, exp->m_client->m_hostname);
++ qword_add(&bp, &blen, p);
++ qword_addint(&bp, &blen, len);
++ qword_addeol(&bp, &blen);
++ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) {
++ close(f);
+ return NULL;
++ }
++ blen = read(f, buf, sizeof(buf));
++ close(f);
+
+- qword_print(f, exp->m_client->m_hostname);
+- qword_print(f, p);
+- qword_printint(f, len);
+- failed = qword_eol(f);
+-
+- if (!failed)
+- failed = (fgets(buf, sizeof(buf), f) == NULL);
+- fclose(f);
+- if (failed)
++ if (blen <= 0 || buf[blen-1] != '\n')
+ return NULL;
++ buf[blen-1] = 0;
++
+ memset(fh.fh_handle, 0, sizeof(fh.fh_handle));
+ fh.fh_size = qword_get(&bp, (char *)fh.fh_handle, NFS3_FHSIZE);
++
+ return &fh;
+ }
+diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c
+index 0675b6a..027e5ac 100644
+--- a/utils/nfsd/nfssvc.c
++++ b/utils/nfsd/nfssvc.c
+@@ -20,6 +20,7 @@
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <stdlib.h>
++#include <string.h>
+
+ #include "nfslib.h"
+ #include "xlog.h"
+--
+2.0.4
+
diff --git a/main/nfs-utils/APKBUILD b/main/nfs-utils/APKBUILD
index dd7b03e190..9cccd6716f 100644
--- a/main/nfs-utils/APKBUILD
+++ b/main/nfs-utils/APKBUILD
@@ -1,8 +1,9 @@
# Contributor: Carlo Landmeter <clandmeter@gmail.com>
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=nfs-utils
-pkgver=1.3.0
-pkgrel=2
+pkgver=1.3.1_rc3
+_basever=1.3.0
+pkgrel=0
pkgdesc="kernel-mode NFS"
url="http://nfs.sourceforge.net/"
arch="all"
@@ -10,11 +11,29 @@ license="GPL"
depends="rpcbind"
makedepends="util-linux-dev libtirpc-dev libcap-dev libevent-dev
libnfsidmap-dev keyutils-dev lvm2-dev krb5-dev sqlite-dev
- autoconf automake libtool"
+ autoconf automake libtool !rpcgen"
subpackages="$pkgname-doc $pkgname-dbg"
[ "$ALPINE_LIBC" != "eglibc" ] && subpackages="$subpackages rpcgen"
-source="http://downloads.sourceforge.net/nfs/$pkgname-$pkgver.tar.bz2
+source="http://downloads.sourceforge.net/nfs/$pkgname-$_basever.tar.bz2
+ nfs-utils-1.3.1-rc3.patch
+ 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
+ 0002-Fix-header-include-for-definition-of-NULL.patch
+ 0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch
+ 0004-replace-__attribute_malloc__-with-the-more-portable-.patch
+ 0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch
+ 0006-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
+ 0007-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
+ 0008-Only-work-around-glibc-bugs-on-glibc.patch
+ 0009-include-libgen.h-for-basename.patch
+ 0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch
+ 0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch
+ 0012-rework-access-to-proc-net-rpc.patch
+
+ nfs-utils-mtab-sym.patch
+ uclibc-getaddrinfo-canonname.patch
+ musl-getservbyport.patch
+
nfs.initd
nfsmount.initd
rpc.gssd.initd
@@ -22,27 +41,12 @@ source="http://downloads.sourceforge.net/nfs/$pkgname-$pkgver.tar.bz2
rpc.pipefs.initd
rpc.statd.initd
rpc.svcgssd.initd
-
nfs.confd
nfs.exports
-
- 0001-Only-work-around-glibc-bugs-on-glibc.patch
- 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
- 0001-include-libgen.h-for-basename.patch
- 0002-Fix-header-include-for-definition-of-NULL.patch
- 0003-replace-__attribute_malloc__-with-the-more-portable-.patch
- 0004-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
- 0005-exportfs-define-_GNU_SOURCE-for-stat64.patch
- 0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch
- 0007-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
-
- nfs-utils-mtab-sym.patch
- uclibc-getaddrinfo-canonname.patch
- musl-getservbyport.patch
"
prepare() {
- cd "$srcdir/$pkgname-$pkgver"
+ cd "$srcdir/$pkgname-$_basever"
for i in $source; do
case $i in
*.patch) msg "Applying $i"
@@ -65,7 +69,7 @@ prepare() {
}
build() {
- cd "$srcdir/$pkgname-$pkgver"
+ cd "$srcdir/$pkgname-$_basever"
./configure \
--build=$CBUILD \
@@ -86,7 +90,7 @@ build() {
}
package() {
- cd "$srcdir/$pkgname-$pkgver"
+ cd "$srcdir/$pkgname-$_basever"
make -j1 DESTDIR="$pkgdir" install
for i in nfs rpc.pipefs rpc.svcgssd nfsmount rpc.idmapd rpc.gssd \
@@ -102,11 +106,27 @@ package() {
rpcgen() {
pkgdesc="Remote Procedure Call (RPC) protocol compiler"
- cd "$srcdir/$pkgname-$pkgver"
+ cd "$srcdir/$pkgname-$_basever"
install -m755 -D tools/rpcgen/rpcgen "$subpkgdir"/usr/bin/rpcgen
}
md5sums="3ac3726eda563946d1f44ac3e5b61d56 nfs-utils-1.3.0.tar.bz2
+4f6b75806437b08742f95eeb8abc640e nfs-utils-1.3.1-rc3.patch
+714afe3a88d6a584d15e167c96c57925 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
+42df50df2888a3384550d4f5667fb515 0002-Fix-header-include-for-definition-of-NULL.patch
+0ee94b77a48b6b364e6b14bb75b992a2 0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch
+2e67ee958bbdcc11d1888c1b8c4329f0 0004-replace-__attribute_malloc__-with-the-more-portable-.patch
+d10a5b570dbbb20accfb4117f605914a 0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch
+4b5e2ed10351eb8d6ab4aa99e65d72aa 0006-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
+93588b3c68825eadf758832a0045f9e2 0007-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
+3b733a0bb274ecdf80bbc09b2a11aa4f 0008-Only-work-around-glibc-bugs-on-glibc.patch
+6424e1113a838ab35eb8623ed82a2352 0009-include-libgen.h-for-basename.patch
+232a07d7d923435a12e51ee74e05cea2 0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch
+5994a46367486129e2892c73dcdc82c2 0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch
+1f6ba2d021b5fa7f7ea4e66b393bd268 0012-rework-access-to-proc-net-rpc.patch
+2b2d228f9947581c924a691a84664fa1 nfs-utils-mtab-sym.patch
+37a82a3a81410b483790ca30d564f4ba uclibc-getaddrinfo-canonname.patch
+b2a716619a34194afbf0dc1c2371b478 musl-getservbyport.patch
9e402e75f23b886fce2f53bec2c1d415 nfs.initd
d514fb87ce5de9909f43d99012352f09 nfsmount.initd
144b0e1f7d32265abe4c499a47af6154 rpc.gssd.initd
@@ -115,20 +135,24 @@ d514fb87ce5de9909f43d99012352f09 nfsmount.initd
37fdb069a5fcabea507012497bb95c53 rpc.statd.initd
20e71ab412555b2dc9b50f346f68e5c8 rpc.svcgssd.initd
09135438d6df50b868bbe5a2260f973c nfs.confd
-4f1bb7b2412ce5952ecb5ec22d8ed99d nfs.exports
-879a1320eefb5a6261693d5dd87a4a09 0001-Only-work-around-glibc-bugs-on-glibc.patch
-e78522fa674479e26efbb07e1f533343 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
-469cd865ee09a353ccffd0a7a1f10ae7 0001-include-libgen.h-for-basename.patch
-db146c3e263de1825ec94dd62167d79c 0002-Fix-header-include-for-definition-of-NULL.patch
-4bf2fd07d60fbebb0b3dd7d5cef34b9b 0003-replace-__attribute_malloc__-with-the-more-portable-.patch
-14b241265b47f698aae7818d2cfb3051 0004-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
-5dc7e475e8bf2ae3df304cf9db6454a7 0005-exportfs-define-_GNU_SOURCE-for-stat64.patch
-334e6124ce5cb3a1c75c426ab6669ba6 0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch
-ed80396c06a84bb86d9f6a1f88b2afbc 0007-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
-2b2d228f9947581c924a691a84664fa1 nfs-utils-mtab-sym.patch
-37a82a3a81410b483790ca30d564f4ba uclibc-getaddrinfo-canonname.patch
-b2a716619a34194afbf0dc1c2371b478 musl-getservbyport.patch"
+4f1bb7b2412ce5952ecb5ec22d8ed99d nfs.exports"
sha256sums="25f1c974018c944347d74eebe89643e1004c822a6145153136b192d1acfaf60d nfs-utils-1.3.0.tar.bz2
+d138a10d4d97e185f1563574019919881a742f2908ef432055b64c4e1a249e2c nfs-utils-1.3.1-rc3.patch
+3ea08ea31560eef7315953d691862174bb1a814ef7d5a0c7d695e922d8723b67 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
+562647aeb295c612889744a4ca7770409ac60ff5953210e5765cac6689d9b0c4 0002-Fix-header-include-for-definition-of-NULL.patch
+bf0af038c1f73a15abaca0242652b9f6666bdff9eae0ac6d4188291abe742769 0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch
+5f95083f65eb4b8f7e2687a1070c0a7a8eee1ec2fb10a56a47e4d69ddd3b9188 0004-replace-__attribute_malloc__-with-the-more-portable-.patch
+993b944d25f03fe7282e1be1d1a294e72d2f879365f08d5c59ea377e51736204 0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch
+5f9ef2978c6cf2c7883984d2ef6bbcb79d88e2155e0b183bfbb8748d1696ba81 0006-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
+cae35793e7548be84fdb4719d92156b7ff167304952fd15d9023e051ec176a82 0007-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
+1de98cbae3b03ea3fba14f1a125bf88b01581e7a9e155377b9d9d98963ced365 0008-Only-work-around-glibc-bugs-on-glibc.patch
+e0eca027b68c191dc96ca89ebe628df18e487b7cbdfb3629231526ef35953de6 0009-include-libgen.h-for-basename.patch
+280ab8bb989c555d880c0aa9b75a6fa83d3bf912ffde75588d914eb9d4cdf54d 0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch
+0bd62ea53c980369990f04b620db725259fa919a351b8ed44e081a8b7a1c221e 0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch
+2d5cc55a6047ef576d6795442b3926f7f686122be26be8566606e0a2d5695b56 0012-rework-access-to-proc-net-rpc.patch
+5a1c6875f43ecc93d5db7bcf84b4ceda16c09b6109c28696eb55d05247511706 nfs-utils-mtab-sym.patch
+7c7451365001f1672abd6fd6dd53da03617a9baa4758ec515b3adf8b7bb7ad93 uclibc-getaddrinfo-canonname.patch
+ae46423ef3383f4a134f578c29a7100d58cde8d8853e88f3ffd66a261d436421 musl-getservbyport.patch
81b546cb98be4678cd22f4da39927d2c79532717d927bfba055af447dbff26a5 nfs.initd
f2f5b54fef59f24a1fc6a8b814dfe2cfdeeb02fd0d5041cff31650e626fe4b75 nfsmount.initd
00d9c29280a83e8458c33139d04a9b38c6fdba9d7cb9b420ca83bf6b10e6435d rpc.gssd.initd
@@ -137,20 +161,24 @@ d651ad9099ea443282476fcedf52c00f0a274eb6a9e4b58a5838780369206973 rpc.pipefs.ini
a727948ccf665b6bb1977ac3014b7086ff654173d1a2be1e2b38a43e97f84ca8 rpc.statd.initd
f1c460d8b0e91e54a551397d755135d05a3728d81de596535bf8bda074455677 rpc.svcgssd.initd
9ca3b7dfbac5bedd818a3637805380f4e873ef8e809c21c26f410c86ac16e03e nfs.confd
-f2aaf1c92e07172adeb65f7f2bc0140c533ae453a3477e99be677ef2e05f2d4b nfs.exports
-6c5be8ce258313d12c1e4ce6ea28d5dcde9c3abc047ac0d8d2bdbf58fe8746f6 0001-Only-work-around-glibc-bugs-on-glibc.patch
-a49a858dd127aeff608e2facd3734765e6113e2e26120d1b5a1a1feacb270157 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
-76d0be35b835ce8facb7eae915f3362268aa6d84a5d1c4a40d72e0f5006ca42e 0001-include-libgen.h-for-basename.patch
-11ea62d8b2c5c9ea050ddd04c43cbe7169c097f2ba1402dff0b5340d88e7a972 0002-Fix-header-include-for-definition-of-NULL.patch
-d0d76cbe0a7929019b29690e2a43bada5f51a18bb4db9172212969c32dfefd38 0003-replace-__attribute_malloc__-with-the-more-portable-.patch
-0a4099ec1c38ed19b3f9fe9c6c068b16aeff37294287ddc0ea637e8bd58af718 0004-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
-7987f2e9a54e31008e0116ca63aba120005ded2b0404f2ab73d866c021975dd3 0005-exportfs-define-_GNU_SOURCE-for-stat64.patch
-ab843e7feb4d51d44bd4d185867b30ed0bbeec2d27ce947689b5b0cb072b0a15 0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch
-47fc077b1093388f6a81bd69eb41dce624d4f5aa4c2cf66f192c23ddd9963f30 0007-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
-5a1c6875f43ecc93d5db7bcf84b4ceda16c09b6109c28696eb55d05247511706 nfs-utils-mtab-sym.patch
-7c7451365001f1672abd6fd6dd53da03617a9baa4758ec515b3adf8b7bb7ad93 uclibc-getaddrinfo-canonname.patch
-ae46423ef3383f4a134f578c29a7100d58cde8d8853e88f3ffd66a261d436421 musl-getservbyport.patch"
+f2aaf1c92e07172adeb65f7f2bc0140c533ae453a3477e99be677ef2e05f2d4b nfs.exports"
sha512sums="9cb9efa26d2b1bd6ae3e0c516ac50b17b4c7993366ae36c7786da734dc8ea4dd7a05f0d6fabb6fba6df36ead8642341a095f1972cb46b400840705356d410a6a nfs-utils-1.3.0.tar.bz2
+a19bea1792e2034e713c49f407512ed6a5d0bfc9c99a8ef96b656b183f90d44554d2f007f28d2ba66e07c9756c9c50d6b5fab3a200fb6ce573e2d7755ec2cf0b nfs-utils-1.3.1-rc3.patch
+4f215d3824142dcf911e57e5772c8d8df4671703c46ba1a28afeca84c94c566034fbaa11214998ae8e636666b32afac6fcfd7b7ee7ba3f4ce469a5952e3aea18 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
+7e6367904135465a06561ab3053362992380eaaa012277697d6f3ae7bbdf022d20cb1e36099ecfb646f414892eb1c32142073561f48ab82f09589473115fb889 0002-Fix-header-include-for-definition-of-NULL.patch
+30161e256160ba258e588412e6dbe5a7b112c19963c489eb01b4b93af329c5f034a6466e44031c4b63f9df9577d30ba8b50102013abdde7bcb40b08d1d222a35 0003-configure.ac-enable-GNU_SOURCE-for-stat64-statfs64.patch
+fea39cdc904cf58c0ddf848c941e8bfda12f30e3a723b9be051042682876d7fbe3bf42b464e1f38993230cb63a7a55d93c08cb26dd6b79b482e10cf4f119515b 0004-replace-__attribute_malloc__-with-the-more-portable-.patch
+8372f6f5b71e9f5e262396c7d319188998e46e91ad763d0acc5e8931d1a12f2240f49dfcab20a71048ec2445e8dbb0d15d8f798978308fd492e146beda4a589e 0005-mountd-use-standard-dev_t-instead-of-glibc-internals.patch
+0d8030816a19ababbc2c3e59960240fe3ed84a058082f7f5bee28129cb9969d14be6d6ebb96d0992928ef76610c94dc5937510db05b4853ef93489ea7134af4b 0006-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
+c665989dfb7d050f87f998373d1b26e816beb87063df625596aca6bf372a65a919d6cf8c8b1664f9aa3422a95e276a0ad5b11b883a40a65c0769fd5f37ea08f9 0007-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
+fe8191a231cd53dd5e44abeb46dbe34bf33df8f8071375c7f80468c12a6de47d16e6eba1342dbd889b16a821491b80f191691fae29f5e4a46f262e3d8beca5ab 0008-Only-work-around-glibc-bugs-on-glibc.patch
+b5042e36f46701ef1163f54e3ef537a07590dec71e39f4fc64ba7a9d0e27a2d7c65af0e639a17867704f212774a375d47bf9bba74ec4c5afffe59c8cee74c588 0009-include-libgen.h-for-basename.patch
+703f1cd9f72faad84fbf60f631acb8e1927a1915addcc64840f6f690e6577837b7a3cefd493fc3b553e724c31352053558395a7a813c90c4186666cd5fd433e1 0010-exportfs-fix-test-of-NULL-pointer-in-host_pton.patch
+9561a979a2313f00c0bbb2ffb3193ca089e5de2f15cf5b6c142e65e04a9401bbc962e490e5b1de026750262a05e5258b286a79781444e7f2ac6bd581b426211a 0011-exportfs-only-do-glibc-specific-hackery-on-glibc.patch
+babaf804265cdd768a2dc8ec798e0a31e8cd8c65c6d8f57f4d254b9b56f336c1c3ec2e8a34ed7765a32720b5d75eb9490ad6269daba51aded8fe29136b3b715e 0012-rework-access-to-proc-net-rpc.patch
+5fd9039a61a0cdaeb57b5332ea545034101e6f15be200b7cf8fc7d0a3d22836a6fc778e0560656c1825808a4dc09046d9923d81b4d1324a6e526b226c657d064 nfs-utils-mtab-sym.patch
+b9f0820773d3ab82cfa9ba603c83f98a71ad2e7205418c1223344b5b3e1bdfbb6aa183ab830df25ded660a4950d0e54098485fa08a4f6b6363a62c0f6c713489 uclibc-getaddrinfo-canonname.patch
+a14fc747cc75f65bb206b28eb4f838ae85687c917893531318d3991adc3ed9914316b97fc507bf34881855c9978ad9d4617f33e464d1a0d746a65b31177687c1 musl-getservbyport.patch
98eeae4b30fe13d6fdeb62d47e05fd5bc577946d84a3fe84703dcc90c58768f0d1886a0aa9262ead3aac5c4bd6d7b1cc2b703fb9603baffad4ac2ead635294f3 nfs.initd
8e720417d7443c6bd4e3bda9e7bf4a61b073009fc1750ec0c7378fb01d726ee827a759c6bc10629606b4f2dbd7884807a9e0b8377382e4968f06ef8e938537ae nfsmount.initd
cd4f763c7cced0eecb03e2d4c8fb1d5fbbddd119a014dee4e9cb881d3750fb01a50daa4475700914785cb1313ceef638b7de4d8dddac90cbab63888cc81938f6 rpc.gssd.initd
@@ -159,16 +187,4 @@ cd4f763c7cced0eecb03e2d4c8fb1d5fbbddd119a014dee4e9cb881d3750fb01a50daa4475700914
cf0272e42310b1ff8d40ff37dc839df2dd4fba4cb408f8fa67ce445e2975b37cafbb35e6d41af2bb462fd05bdd444ba297a156daadcf50e1d73b322d6abeea17 rpc.statd.initd
844e8d41a6a8b632d98585724aca2e9ae596f72c67e17e4e8fb9eb81e6c58eed9e10cf8b2a96896dba8fd1efaa95d846954e712bdf3402a847ae17742dae2157 rpc.svcgssd.initd
1711803f848f73fef9fa74bd572fa7643c586f06eeedf62ed91bd2aa06ad59c7b1f1c585b6f7b7a8ce67ff7fd6b601d88dc99ca1000dd1d3f5991f420da9761b nfs.confd
-70f96bb3a465ee0fa857a6e511051ca3ced9f5a5d1e6b8b32eec843a2067f2475d8979c724a3661de0a2b078eef143f55d75ed184d823841d9de5038da91fb91 nfs.exports
-9d0c4498691019a515cc194dd717d139230aa29ac1db4aa74beecd4817484f8b49632ddb33abd7d649940134f663e24a07fdf35fcaec72312aabc633e284e51e 0001-Only-work-around-glibc-bugs-on-glibc.patch
-1b59dcb7f7a11a0cd8ee4ab25f22f85a57a3e8fd5fb54eb6add1a4933b5a96d333b3bff3955d36999a1f9b0b312b52c83e4efc5ed0cdecbd305a95e676129f6d 0001-conffile-use-standard-uint-_t-and-unsigned-char.patch
-070fe49430d973c0d0142a0ce65ece2265abc34b0e53661d6b5eda9b911f7bf9b5b6561125b6bbb1a4739f92b916d5bf3080b67c87a429e959454b13f5aa6c38 0001-include-libgen.h-for-basename.patch
-18f5c50ace27d88984b85b0fa529257ba151ec2295af8f66b3637b32df817063426ab56d1c9eca4b6437614338ff74865cd918c12695927b4da6af6b639dd0ed 0002-Fix-header-include-for-definition-of-NULL.patch
-bdef9397da387b51b9774e21c92b0850c082d6b250bfbecc680e5b22cd8fb7f14fea7e4f4febeefbd56494bfe4e56f585880664d6413b0f1290eac06d5b7712f 0003-replace-__attribute_malloc__-with-the-more-portable-.patch
-495642168b11a642581dd574b2f0530a5bf7b6c5e89fae4926d8427afc6bb01e5170d9348207d3b97af7d70b795ebf208fb04a41636556d9ca66c0cee1554962 0004-Allow-usage-of-getrpcbynumber-when-getrpcbynumber_r-.patch
-80ba9146befdcb9d60625f9d224145a34cae2614ff69e91357b3c3049ff983f82ebad1b29a8a17ae2e16062f685d1660cc6007bb4287fcdc6b7e889a1b8a3f82 0005-exportfs-define-_GNU_SOURCE-for-stat64.patch
-c41e853bc156ab37cfe074a9c14d13fa94d3efff1351861668fe09cc6f1079b8d695ddb857a214db607500cef946d1aba45d748bd839a0184cd8ea5f34f8cb2d 0006-mountd-define-_GNU_SOURCE-for-statfs64-and-use-stand.patch
-939c11c66532c5a70699fa01744dfe2ffb2926307c771e055f4e04132b58f4715d7f81e233911a4ac1c0715190e64b7d2fff3a007c02cea939fee98351b3ca16 0007-nfsstat-replace-the-legacy-SA_ONESHOT-with-standard-.patch
-5fd9039a61a0cdaeb57b5332ea545034101e6f15be200b7cf8fc7d0a3d22836a6fc778e0560656c1825808a4dc09046d9923d81b4d1324a6e526b226c657d064 nfs-utils-mtab-sym.patch
-b9f0820773d3ab82cfa9ba603c83f98a71ad2e7205418c1223344b5b3e1bdfbb6aa183ab830df25ded660a4950d0e54098485fa08a4f6b6363a62c0f6c713489 uclibc-getaddrinfo-canonname.patch
-a14fc747cc75f65bb206b28eb4f838ae85687c917893531318d3991adc3ed9914316b97fc507bf34881855c9978ad9d4617f33e464d1a0d746a65b31177687c1 musl-getservbyport.patch"
+70f96bb3a465ee0fa857a6e511051ca3ced9f5a5d1e6b8b32eec843a2067f2475d8979c724a3661de0a2b078eef143f55d75ed184d823841d9de5038da91fb91 nfs.exports"
diff --git a/main/nfs-utils/nfs-utils-1.3.1-rc3.patch b/main/nfs-utils/nfs-utils-1.3.1-rc3.patch
new file mode 100644
index 0000000000..9e4048b59c
--- /dev/null
+++ b/main/nfs-utils/nfs-utils-1.3.1-rc3.patch
@@ -0,0 +1,1086 @@
+diff --git a/Makefile.am b/Makefile.am
+index ae7cd16..5824adc 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -54,13 +54,13 @@ install-data-hook:
+ touch $(DESTDIR)$(statedir)/xtab; chmod 644 $(DESTDIR)$(statedir)/xtab
+ touch $(DESTDIR)$(statedir)/etab; chmod 644 $(DESTDIR)$(statedir)/etab
+ touch $(DESTDIR)$(statedir)/rmtab; chmod 644 $(DESTDIR)$(statedir)/rmtab
+- mkdir -p $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak
+- touch $(DESTDIR)$(statedir)/state
+- chmod go-rwx $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
+- -chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
++ mkdir -p $(DESTDIR)$(statdpath)/sm $(DESTDIR)$(statdpath)/sm.bak
++ touch $(DESTDIR)$(statdpath)/state
++ chmod go-rwx $(DESTDIR)$(statdpath)/sm $(DESTDIR)$(statdpath)/sm.bak $(DESTDIR)$(statdpath)/state
++ -chown $(statduser) $(DESTDIR)$(statdpath)/sm $(DESTDIR)$(statdpath)/sm.bak $(DESTDIR)$(statdpath)/state
+
+ uninstall-hook:
+ rm $(DESTDIR)$(statedir)/xtab
+ rm $(DESTDIR)$(statedir)/etab
+ rm $(DESTDIR)$(statedir)/rmtab
+- rm $(DESTDIR)$(statedir)/state
++ rm $(DESTDIR)$(statdpath)/state
+diff --git a/configure.ac b/configure.ac
+index 7b93de6..408f4c8 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -411,7 +411,7 @@ AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
+ getnameinfo getrpcbyname getifaddrs \
+ gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
+ ppoll realpath rmdir select socket strcasecmp strchr strdup \
+- strerror strrchr strtol strtoul sigprocmask])
++ strerror strrchr strtol strtoul sigprocmask name_to_handle_at])
+
+
+ dnl *************************************************************
+diff --git a/support/export/client.c b/support/export/client.c
+index dbf47b9..f85e11c 100644
+--- a/support/export/client.c
++++ b/support/export/client.c
+@@ -482,8 +482,12 @@ add_name(char *old, const char *add)
+ else
+ cp = cp + strlen(cp);
+ }
+- strncpy(new, old, cp-old);
+- new[cp-old] = 0;
++ if (old) {
++ strncpy(new, old, cp-old);
++ new[cp-old] = 0;
++ } else {
++ new[0] = 0;
++ }
+ if (cp != old && !*cp)
+ strcat(new, ",");
+ strcat(new, add);
+diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
+index e46105d..1fb3e2f 100644
+--- a/tools/mountstats/mountstats.py
++++ b/tools/mountstats/mountstats.py
+@@ -371,7 +371,7 @@ def parse_stats_file(filename):
+ ms_dict = dict()
+ key = ''
+
+- f = file(filename)
++ f = open(filename)
+ for line in f.readlines():
+ words = line.split()
+ if len(words) == 0:
+diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
+index 341cdbf..61d15a5 100644
+--- a/tools/nfs-iostat/nfs-iostat.py
++++ b/tools/nfs-iostat/nfs-iostat.py
+@@ -213,7 +213,8 @@ class DeviceData:
+ # the reference to them. so we build new lists here
+ # for the result object.
+ for op in result.__rpc_data['ops']:
+- result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op])
++ result.__rpc_data[op] = list(map(
++ difference, self.__rpc_data[op], old_stats.__rpc_data[op]))
+
+ # update the remaining keys we care about
+ result.__rpc_data['rpcsends'] -= old_stats.__rpc_data['rpcsends']
+@@ -243,27 +244,15 @@ class DeviceData:
+ """Print attribute cache efficiency stats
+ """
+ nfs_stats = self.__nfs_data
+- getattr_stats = self.__rpc_data['GETATTR']
+-
+- if nfs_stats['inoderevalidates'] != 0:
+- getattr_ops = float(getattr_stats[1])
+- opens = float(nfs_stats['vfsopen'])
+- revalidates = float(nfs_stats['inoderevalidates']) - opens
+- if revalidates != 0:
+- ratio = ((revalidates - getattr_ops) * 100) / revalidates
+- else:
+- ratio = 0.0
+-
+- data_invalidates = float(nfs_stats['datainvalidates'])
+- attr_invalidates = float(nfs_stats['attrinvalidates'])
+
+- print()
+- print('%d inode revalidations, hitting in cache %4.2f%% of the time' % \
+- (revalidates, ratio))
+- print('%d open operations (mandatory GETATTR requests)' % opens)
+- if getattr_ops != 0:
+- print('%4.2f%% of GETATTRs resulted in data cache invalidations' % \
+- ((data_invalidates * 100) / getattr_ops))
++ print()
++ print('%d VFS opens' % (nfs_stats['vfsopen']))
++ print('%d inoderevalidates (forced GETATTRs)' % \
++ (nfs_stats['inoderevalidates']))
++ print('%d page cache invalidations' % \
++ (nfs_stats['datainvalidates']))
++ print('%d attribute cache invalidations' % \
++ (nfs_stats['attrinvalidates']))
+
+ def __print_dir_cache_stats(self, sample_time):
+ """Print directory stats
+@@ -353,15 +342,21 @@ class DeviceData:
+ exe_per_op = 0.0
+
+ op += ':'
+- print('%s' % op.lower().ljust(15), end='')
+- print(' ops/s\t\t kB/s\t\t kB/op\t\tretrans\t\tavg RTT (ms)\tavg exe (ms)')
+-
+- print('\t\t%7.3f' % (ops / sample_time), end='')
+- print('\t%7.3f' % (kilobytes / sample_time), end='')
+- print('\t%7.3f' % kb_per_op, end='')
+- print(' %7d (%3.1f%%)' % (retrans, retrans_percent), end='')
+- print('\t%7.3f' % rtt_per_op, end='')
+- print('\t%7.3f' % exe_per_op)
++ print(format(op.lower(), '<16s'), end='')
++ print(format('ops/s', '>8s'), end='')
++ print(format('kB/s', '>16s'), end='')
++ print(format('kB/op', '>16s'), end='')
++ print(format('retrans', '>16s'), end='')
++ print(format('avg RTT (ms)', '>16s'), end='')
++ print(format('avg exe (ms)', '>16s'))
++
++ print(format((ops / sample_time), '>24.3f'), end='')
++ print(format((kilobytes / sample_time), '>16.3f'), end='')
++ print(format(kb_per_op, '>16.3f'), end='')
++ retransmits = '{0:>10.0f} ({1:>3.1f}%)'.format(retrans, retrans_percent).strip()
++ print(format(retransmits, '>16'), end='')
++ print(format(rtt_per_op, '>16.3f'), end='')
++ print(format(exe_per_op, '>16.3f'))
+
+ def ops(self, sample_time):
+ sends = float(self.__rpc_data['rpcsends'])
+@@ -391,9 +386,10 @@ class DeviceData:
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint']))
+ print()
+
+- print(' op/s\t\trpc bklog')
+- print('%7.2f' % (sends / sample_time), end='')
+- print('\t%7.2f' % backlog)
++ print(format('ops/s', '>16') + format('rpc bklog', '>16'))
++ print(format((sends / sample_time), '>16.3f'), end='')
++ print(format(backlog, '>16.3f'))
++ print()
+
+ if which == 0:
+ self.__print_rpc_op_stats('READ', sample_time)
+diff --git a/tools/nfs-iostat/nfsiostat.man b/tools/nfs-iostat/nfsiostat.man
+index 3ec245d..b477a9a 100644
+--- a/tools/nfs-iostat/nfsiostat.man
++++ b/tools/nfs-iostat/nfsiostat.man
+@@ -38,6 +38,61 @@ If one or more
+ .I <mount point>
+ names are specified, statistics for only these mount points will
+ be displayed. Otherwise, all NFS mount points on the client are listed.
++.TP
++The meaning of each column of \fBnfsiostat\fR's output is the following:
++.RS 8
++- \fBop/s\fR
++.RS
++This is the number of operations per second.
++.RS
++.RE
++.RE
++.RE
++.RS 8
++- \fBrpc bklog\fR
++.RS
++This is the length of the backlog queue.
++.RE
++.RE
++.RE
++.RS 8
++- \fBkB/s\fR
++.RS
++This is the number of kB written/read per second.
++.RE
++.RE
++.RE
++.RS 8
++- \fBkB/op\fR
++.RS
++This is the number of kB written/read per each operation.
++.RE
++.RE
++.RE
++.RS 8
++- \fBretrans\fR
++.RS
++This is the number of retransmissions.
++.RE
++.RE
++.RE
++.RS 8
++- \fBavg RTT (ms)\fR
++.RS
++This is the duration from the time that client's kernel sends the RPC request until the time it receives the reply.
++.RE
++.RE
++.RE
++.RS 8
++- \fBavg exe (ms)\fR
++.RS
++This is the duration from the time that NFS client does the RPC request to its kernel until the RPC request is completed, this includes the RTT time above.
++.RE
++.RE
++.RE
++.TP
++Note that if an interval is used as argument to \fBnfsiostat\fR, then the diffrence from previous interval will be displayed, otherwise the results will be from the time that the share was mounted.
++
+ .SH OPTIONS
+ .TP
+ .B \-a " or " \-\-attr
+diff --git a/utils/gssd/Makefile.am b/utils/gssd/Makefile.am
+index a9a3e42..af59791 100644
+--- a/utils/gssd/Makefile.am
++++ b/utils/gssd/Makefile.am
+@@ -18,11 +18,13 @@ COMMON_SRCS = \
+ context_lucid.c \
+ gss_util.c \
+ gss_oids.c \
++ gss_names.c \
+ err_util.c \
+ \
+ context.h \
+ err_util.h \
+ gss_oids.h \
++ gss_names.h \
+ gss_util.h
+
+ gssd_SOURCES = \
+diff --git a/utils/gssd/gss_names.c b/utils/gssd/gss_names.c
+new file mode 100644
+index 0000000..047069d
+--- /dev/null
++++ b/utils/gssd/gss_names.c
+@@ -0,0 +1,138 @@
++/*
++ Copyright (c) 2000 The Regents of the University of Michigan.
++ All rights reserved.
++
++ Copyright (c) 2002 Bruce Fields <bfields@UMICH.EDU>
++
++ 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.
++*/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif /* HAVE_CONFIG_H */
++
++#include <sys/param.h>
++#include <sys/stat.h>
++#include <rpc/rpc.h>
++
++#include <pwd.h>
++#include <stdio.h>
++#include <unistd.h>
++#include <ctype.h>
++#include <string.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <nfsidmap.h>
++#include <nfslib.h>
++#include <time.h>
++
++#include "svcgssd.h"
++#include "gss_util.h"
++#include "err_util.h"
++#include "context.h"
++#include "misc.h"
++#include "gss_oids.h"
++#include "svcgssd_krb5.h"
++
++static int
++get_krb5_hostbased_name(gss_buffer_desc *name, char **hostbased_name)
++{
++ char *p, *sname = NULL;
++ if (strchr(name->value, '@') && strchr(name->value, '/')) {
++ if ((sname = calloc(name->length, 1)) == NULL) {
++ printerr(0, "ERROR: get_krb5_hostbased_name failed "
++ "to allocate %d bytes\n", name->length);
++ return -1;
++ }
++ /* read in name and instance and replace '/' with '@' */
++ sscanf(name->value, "%[^@]", sname);
++ p = strrchr(sname, '/');
++ if (p == NULL) { /* The '@' preceeded the '/' */
++ free(sname);
++ return -1;
++ }
++ *p = '@';
++ }
++ *hostbased_name = sname;
++ return 0;
++}
++
++int
++get_hostbased_client_name(gss_name_t client_name, gss_OID mech,
++ char **hostbased_name)
++{
++ u_int32_t maj_stat, min_stat;
++ gss_buffer_desc name;
++ gss_OID name_type = GSS_C_NO_OID;
++ char *cname;
++ int res = -1;
++
++ *hostbased_name = NULL; /* preset in case we fail */
++
++ /* Get the client's gss authenticated name */
++ maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
++ if (maj_stat != GSS_S_COMPLETE) {
++ pgsserr("get_hostbased_client_name: gss_display_name",
++ maj_stat, min_stat, mech);
++ goto out_err;
++ }
++ if (name.length >= 0xffff) { /* don't overflow */
++ printerr(0, "ERROR: get_hostbased_client_name: "
++ "received gss_name is too long (%d bytes)\n",
++ name.length);
++ goto out_rel_buf;
++ }
++
++ /* For Kerberos, transform the NT_KRB5_PRINCIPAL name to
++ * an NT_HOSTBASED_SERVICE name */
++ if (g_OID_equal(&krb5oid, mech)) {
++ if (get_krb5_hostbased_name(&name, &cname) == 0)
++ *hostbased_name = cname;
++ } else {
++ printerr(1, "WARNING: unknown/unsupport mech OID\n");
++ }
++
++ res = 0;
++out_rel_buf:
++ gss_release_buffer(&min_stat, &name);
++out_err:
++ return res;
++}
++
++void
++get_hostbased_client_buffer(gss_name_t client_name, gss_OID mech,
++ gss_buffer_t buf)
++{
++ char *hname;
++
++ if (!get_hostbased_client_name(client_name, mech, &hname)) {
++ buf->length = strlen(hname) + 1;
++ buf->value = hname;
++ } else {
++ buf->length = 0;
++ buf->value = NULL;
++ }
++}
+diff --git a/utils/gssd/gss_names.h b/utils/gssd/gss_names.h
+new file mode 100644
+index 0000000..ce182f7
+--- /dev/null
++++ b/utils/gssd/gss_names.h
+@@ -0,0 +1,36 @@
++/*
++ Copyright (c) 2000 The Regents of the University of Michigan.
++ All rights reserved.
++
++ Copyright (c) 2002 Bruce Fields <bfields@UMICH.EDU>
++
++ 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.
++*/
++
++extern int get_hostbased_client_name(gss_name_t client_name, gss_OID mech,
++ char **hostbased_name);
++extern void get_hostbased_client_buffer(gss_name_t client_name,
++ gss_OID mech, gss_buffer_t buf);
+diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
+index 611ef1a..6b8b863 100644
+--- a/utils/gssd/gssd.c
++++ b/utils/gssd/gssd.c
+@@ -64,6 +64,7 @@ char *ccachesearch[GSSD_MAX_CCACHE_SEARCH + 1];
+ int use_memcache = 0;
+ int root_uses_machine_creds = 1;
+ unsigned int context_timeout = 0;
++unsigned int rpc_timeout = 5;
+ char *preferred_realm = NULL;
+ int pipefds[2] = { -1, -1 };
+
+@@ -105,7 +106,7 @@ main(int argc, char *argv[])
+ char *progname;
+
+ memset(ccachesearch, 0, sizeof(ccachesearch));
+- while ((opt = getopt(argc, argv, "DfvrlmnMp:k:d:t:R:")) != -1) {
++ while ((opt = getopt(argc, argv, "DfvrlmnMp:k:d:t:T:R:")) != -1) {
+ switch (opt) {
+ case 'f':
+ fg = 1;
+@@ -143,6 +144,9 @@ main(int argc, char *argv[])
+ case 't':
+ context_timeout = atoi(optarg);
+ break;
++ case 'T':
++ rpc_timeout = atoi(optarg);
++ break;
+ case 'R':
+ preferred_realm = strdup(optarg);
+ break;
+diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
+index 56a18d6..48f4ad8 100644
+--- a/utils/gssd/gssd.h
++++ b/utils/gssd/gssd.h
+@@ -66,6 +66,7 @@ extern char *ccachesearch[];
+ extern int use_memcache;
+ extern int root_uses_machine_creds;
+ extern unsigned int context_timeout;
++extern unsigned int rpc_timeout;
+ extern char *preferred_realm;
+ extern int pipefds[2];
+
+diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man
+index ac13fd4..ea58fa0 100644
+--- a/utils/gssd/gssd.man
++++ b/utils/gssd/gssd.man
+@@ -289,6 +289,14 @@ new kernel contexts to be negotiated after
+ seconds, which allows changing Kerberos tickets and identities frequently.
+ The default is no explicit timeout, which means the kernel context will live
+ the lifetime of the Kerberos service ticket used in its creation.
++.TP
++.B -T timeout
++Timeout, in seconds, to create an RPC connection with a server while
++establishing an authenticated gss context for a user.
++The default timeout is set to 5 seconds.
++If you get messages like "WARNING: can't create tcp rpc_clnt to server
++%servername% for user with uid %uid%: RPC: Remote system error -
++Connection timed out", you should consider an increase of this timeout.
+ .SH SEE ALSO
+ .BR rpc.svcgssd (8),
+ .BR kerberos (1),
+diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c
+index 9970028..6946ab6 100644
+--- a/utils/gssd/gssd_main_loop.c
++++ b/utils/gssd/gssd_main_loop.c
+@@ -173,6 +173,10 @@ topdirs_init_list(void)
+ if (ret)
+ goto out_err;
+ }
++ if (TAILQ_EMPTY(&topdirs_list)) {
++ printerr(0, "ERROR: rpc_pipefs directory '%s' is empty!\n", pipefs_dir);
++ return -1;
++ }
+ closedir(pipedir);
+ return 0;
+ out_err:
+@@ -233,9 +237,10 @@ gssd_run()
+ sigaddset(&set, DNOTIFY_SIGNAL);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+
+- if (topdirs_init_list() != 0)
+- return;
+-
++ if (topdirs_init_list() != 0) {
++ /* Error msg is already printed */
++ exit(1);
++ }
+ init_client_list();
+
+ printerr(1, "beginning poll\n");
+diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
+index 33cfeb2..121feb1 100644
+--- a/utils/gssd/gssd_proc.c
++++ b/utils/gssd/gssd_proc.c
+@@ -77,6 +77,7 @@
+ #include "context.h"
+ #include "nfsrpc.h"
+ #include "nfslib.h"
++#include "gss_names.h"
+
+ /*
+ * pollarray:
+@@ -217,7 +218,7 @@ get_servername(const char *name, const struct sockaddr *sa, const char *addr)
+ NI_NAMEREQD);
+ if (err) {
+ printerr(0, "ERROR: unable to resolve %s to hostname: %s\n",
+- addr, err == EAI_SYSTEM ? strerror(err) :
++ addr, err == EAI_SYSTEM ? strerror(errno) :
+ gai_strerror(err));
+ return NULL;
+ }
+@@ -681,19 +682,25 @@ parse_enctypes(char *enctypes)
+ return 0;
+ }
+
+-static int
++static void
+ do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
+- gss_buffer_desc *context_token, OM_uint32 lifetime_rec)
++ gss_buffer_desc *context_token, OM_uint32 lifetime_rec,
++ gss_buffer_desc *acceptor)
+ {
+ char *buf = NULL, *p = NULL, *end = NULL;
+ unsigned int timeout = context_timeout;
+ unsigned int buf_size = 0;
+
+- printerr(1, "doing downcall lifetime_rec %u\n", lifetime_rec);
++ printerr(1, "doing downcall: lifetime_rec=%u acceptor=%.*s\n",
++ lifetime_rec, acceptor->length, acceptor->value);
+ buf_size = sizeof(uid) + sizeof(timeout) + sizeof(pd->pd_seq_win) +
+ sizeof(pd->pd_ctx_hndl.length) + pd->pd_ctx_hndl.length +
+- sizeof(context_token->length) + context_token->length;
++ sizeof(context_token->length) + context_token->length +
++ sizeof(acceptor->length) + acceptor->length;
+ p = buf = malloc(buf_size);
++ if (!buf)
++ goto out_err;
++
+ end = buf + buf_size;
+
+ /* context_timeout set by -t option overrides context lifetime */
+@@ -704,14 +711,15 @@ do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
+ if (WRITE_BYTES(&p, end, pd->pd_seq_win)) goto out_err;
+ if (write_buffer(&p, end, &pd->pd_ctx_hndl)) goto out_err;
+ if (write_buffer(&p, end, context_token)) goto out_err;
++ if (write_buffer(&p, end, acceptor)) goto out_err;
+
+ if (write(k5_fd, buf, p - buf) < p - buf) goto out_err;
+- if (buf) free(buf);
+- return 0;
++ free(buf);
++ return;
+ out_err:
+- if (buf) free(buf);
++ free(buf);
+ printerr(1, "Failed to write downcall!\n");
+- return -1;
++ return;
+ }
+
+ static int
+@@ -842,7 +850,7 @@ create_auth_rpc_client(struct clnt_info *clp,
+ OM_uint32 min_stat;
+ char rpc_errmsg[1024];
+ int protocol;
+- struct timeval timeout = {5, 0};
++ struct timeval timeout;
+ struct sockaddr *addr = (struct sockaddr *) &clp->addr;
+ socklen_t salen;
+
+@@ -910,6 +918,10 @@ create_auth_rpc_client(struct clnt_info *clp,
+ if (!populate_port(addr, salen, clp->prog, clp->vers, protocol))
+ goto out_fail;
+
++ /* set the timeout according to the requested valued */
++ timeout.tv_sec = (long) rpc_timeout;
++ timeout.tv_usec = (long) 0;
++
+ rpc_clnt = nfs_get_rpcclient(addr, salen, protocol, clp->prog,
+ clp->vers, &timeout);
+ if (!rpc_clnt) {
+@@ -1031,6 +1043,9 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ gss_cred_id_t gss_cred;
+ OM_uint32 maj_stat, min_stat, lifetime_rec;
+ pid_t pid;
++ gss_name_t gacceptor = GSS_C_NO_NAME;
++ gss_OID mech;
++ gss_buffer_desc acceptor = {0};
+
+ pid = fork();
+ switch(pid) {
+@@ -1171,15 +1186,24 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ goto out_return_error;
+ }
+
+- /* Grab the context lifetime to pass to the kernel. lifetime_rec
+- * is set to zero on error */
+- maj_stat = gss_inquire_context(&min_stat, pd.pd_ctx, NULL, NULL,
+- &lifetime_rec, NULL, NULL, NULL, NULL);
++ /* Grab the context lifetime and acceptor name out of the ctx. */
++ maj_stat = gss_inquire_context(&min_stat, pd.pd_ctx, NULL, &gacceptor,
++ &lifetime_rec, &mech, NULL, NULL, NULL);
+
+- if (maj_stat)
+- printerr(1, "WARNING: Failed to inquire context for lifetme "
+- "maj_stat %u\n", maj_stat);
++ if (maj_stat != GSS_S_COMPLETE) {
++ printerr(1, "WARNING: Failed to inquire context "
++ "maj_stat (0x%x)\n", maj_stat);
++ lifetime_rec = 0;
++ } else {
++ get_hostbased_client_buffer(gacceptor, mech, &acceptor);
++ gss_release_name(&min_stat, &gacceptor);
++ }
+
++ /*
++ * The serialization can mean turning pd.pd_ctx into a lucid context. If
++ * that happens then the pd.pd_ctx will be unusable, so we must never
++ * try to use it after this point.
++ */
+ if (serialize_context_for_kernel(&pd.pd_ctx, &token, &krb5oid, NULL)) {
+ printerr(0, "WARNING: Failed to serialize krb5 context for "
+ "user with uid %d for server %s\n",
+@@ -1187,9 +1211,10 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ goto out_return_error;
+ }
+
+- do_downcall(fd, uid, &pd, &token, lifetime_rec);
++ do_downcall(fd, uid, &pd, &token, lifetime_rec, &acceptor);
+
+ out:
++ gss_release_buffer(&min_stat, &acceptor);
+ if (token.value)
+ free(token.value);
+ #ifdef HAVE_AUTHGSS_FREE_PRIVATE_DATA
+diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c
+index 3757d51..5bdb438 100644
+--- a/utils/gssd/svcgssd_proc.c
++++ b/utils/gssd/svcgssd_proc.c
+@@ -59,6 +59,7 @@
+ #include "misc.h"
+ #include "gss_oids.h"
+ #include "svcgssd_krb5.h"
++#include "gss_names.h"
+
+ extern char * mech2file(gss_OID mech);
+ #define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel"
+@@ -315,71 +316,6 @@ print_hexl(const char *description, unsigned char *cp, int length)
+ }
+ #endif
+
+-static int
+-get_krb5_hostbased_name (gss_buffer_desc *name, char **hostbased_name)
+-{
+- char *p, *sname = NULL;
+- if (strchr(name->value, '@') && strchr(name->value, '/')) {
+- if ((sname = calloc(name->length, 1)) == NULL) {
+- printerr(0, "ERROR: get_krb5_hostbased_name failed "
+- "to allocate %d bytes\n", name->length);
+- return -1;
+- }
+- /* read in name and instance and replace '/' with '@' */
+- sscanf(name->value, "%[^@]", sname);
+- p = strrchr(sname, '/');
+- if (p == NULL) { /* The '@' preceeded the '/' */
+- free(sname);
+- return -1;
+- }
+- *p = '@';
+- }
+- *hostbased_name = sname;
+- return 0;
+-}
+-
+-static int
+-get_hostbased_client_name(gss_name_t client_name, gss_OID mech,
+- char **hostbased_name)
+-{
+- u_int32_t maj_stat, min_stat;
+- gss_buffer_desc name;
+- gss_OID name_type = GSS_C_NO_OID;
+- char *cname;
+- int res = -1;
+-
+- *hostbased_name = NULL; /* preset in case we fail */
+-
+- /* Get the client's gss authenticated name */
+- maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
+- if (maj_stat != GSS_S_COMPLETE) {
+- pgsserr("get_hostbased_client_name: gss_display_name",
+- maj_stat, min_stat, mech);
+- goto out_err;
+- }
+- if (name.length >= 0xffff) { /* don't overflow */
+- printerr(0, "ERROR: get_hostbased_client_name: "
+- "received gss_name is too long (%d bytes)\n",
+- name.length);
+- goto out_rel_buf;
+- }
+-
+- /* For Kerberos, transform the NT_KRB5_PRINCIPAL name to
+- * an NT_HOSTBASED_SERVICE name */
+- if (g_OID_equal(&krb5oid, mech)) {
+- if (get_krb5_hostbased_name(&name, &cname) == 0)
+- *hostbased_name = cname;
+- } else {
+- printerr(1, "WARNING: unknown/unsupport mech OID\n");
+- }
+-
+- res = 0;
+-out_rel_buf:
+- gss_release_buffer(&min_stat, &name);
+-out_err:
+- return res;
+-}
+-
+ void
+ handle_nullreq(FILE *f) {
+ /* XXX initialize to a random integer to reduce chances of unnecessary
+diff --git a/utils/mount/error.c b/utils/mount/error.c
+index f8fc13f..e06f598 100644
+--- a/utils/mount/error.c
++++ b/utils/mount/error.c
+@@ -215,8 +215,12 @@ void mount_error(const char *spec, const char *mount_point, int error)
+ progname);
+ break;
+ case ENOTDIR:
+- nfs_error(_("%s: mount point %s is not a directory"),
+- progname, mount_point);
++ if (spec)
++ nfs_error(_("%s: mount spec %s or point %s is not a "
++ "directory"), progname, spec, mount_point);
++ else
++ nfs_error(_("%s: mount point %s is not a directory"),
++ progname, mount_point);
+ break;
+ case EBUSY:
+ nfs_error(_("%s: %s is busy or already mounted"),
+diff --git a/utils/mount/nfsmount.conf b/utils/mount/nfsmount.conf
+index 9b8ff4a..aeb3023 100644
+--- a/utils/mount/nfsmount.conf
++++ b/utils/mount/nfsmount.conf
+@@ -133,3 +133,12 @@
+ # RPCGSS security flavors
+ # [none, sys, krb5, krb5i, krb5p ]
+ # Sec=sys
++#
++# Allow Signals to interrupt file operations
++# Intr=True
++#
++# Specifies how the kernel manages its cache of directory
++# Lookupcache=all|none|pos|positive
++#
++# Turn of the caching of that access time
++# noatime=True
+diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
+index 9a1bb27..b0cc6a8 100644
+--- a/utils/mountd/cache.c
++++ b/utils/mountd/cache.c
+@@ -377,6 +377,86 @@ static char *next_mnt(void **v, char *p)
+ return me->mnt_dir;
+ }
+
++/* same_path() check is two paths refer to the same directory.
++ * We don't rely on 'strcmp()' as some filesystems support case-insensitive
++ * names and we might have two different names for the one directory.
++ * Theoretically the lengths of the names could be different, but the
++ * number of components must be the same.
++ * So if the paths have the same number of components (but aren't identical)
++ * we ask the kernel if they are the same thing.
++ * By preference we use name_to_handle_at(), as the mntid it returns
++ * will distinguish between bind-mount points. If that isn't available
++ * we fall back on lstat, which is usually good enough.
++ */
++static inline int count_slashes(char *p)
++{
++ int cnt = 0;
++ while (*p)
++ if (*p++ == '/')
++ cnt++;
++ return cnt;
++}
++
++static int same_path(char *child, char *parent, int len)
++{
++ static char p[PATH_MAX];
++ struct stat sc, sp;
++
++ if (len <= 0)
++ len = strlen(child);
++ strncpy(p, child, len);
++ p[len] = 0;
++ if (strcmp(p, parent) == 0)
++ return 1;
++
++ /* If number of '/' are different, they must be different */
++ if (count_slashes(p) != count_slashes(parent))
++ return 0;
++
++#if HAVE_NAME_TO_HANDLE_AT
++ struct {
++ struct file_handle fh;
++ unsigned char handle[128];
++ } fchild, fparent;
++ int mnt_child, mnt_parent;
++
++ fchild.fh.handle_bytes = 128;
++ fparent.fh.handle_bytes = 128;
++ if (name_to_handle_at(AT_FDCWD, p, &fchild.fh, &mnt_child, 0) != 0) {
++ if (errno == ENOSYS)
++ goto fallback;
++ return 0;
++ }
++ if (name_to_handle_at(AT_FDCWD, parent, &fparent.fh, &mnt_parent, 0) != 0)
++ return 0;
++
++ if (mnt_child != mnt_parent ||
++ fchild.fh.handle_bytes != fparent.fh.handle_bytes ||
++ fchild.fh.handle_type != fparent.fh.handle_type ||
++ memcmp(fchild.handle, fparent.handle,
++ fchild.fh.handle_bytes) != 0)
++ return 0;
++
++ return 1;
++fallback:
++#endif
++
++ /* This is nearly good enough. However if a directory is
++ * bind-mounted in two places and both are exported, it
++ * could give a false positive
++ */
++ if (lstat(p, &sc) != 0)
++ return 0;
++ if (lstat(parent, &sp) != 0)
++ return 0;
++ if (sc.st_dev != sp.st_dev)
++ return 0;
++ if (sc.st_ino != sp.st_ino)
++ return 0;
++
++ return 1;
++}
++
+ static int is_subdirectory(char *child, char *parent)
+ {
+ /* Check is child is strictly a subdirectory of
+@@ -387,7 +467,7 @@ static int is_subdirectory(char *child, char *parent)
+ if (strcmp(parent, "/") == 0 && child[1] != 0)
+ return 1;
+
+- return (strncmp(child, parent, l) == 0 && child[l] == '/');
++ return (same_path(child, parent, l) && child[l] == '/');
+ }
+
+ static int path_matches(nfs_export *exp, char *path)
+@@ -396,7 +476,7 @@ static int path_matches(nfs_export *exp, char *path)
+ * exact match, or does the export have CROSSMOUNT, and path
+ * is a descendant?
+ */
+- return strcmp(path, exp->m_export.e_path) == 0
++ return same_path(path, exp->m_export.e_path, 0)
+ || ((exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
+ && is_subdirectory(path, exp->m_export.e_path));
+ }
+diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man
+index e59a559..a8828ae 100644
+--- a/utils/mountd/mountd.man
++++ b/utils/mountd/mountd.man
+@@ -86,7 +86,7 @@ Turn on debugging. Valid kinds are: all, auth, call, general and parse.
+ .B \-F " or " \-\-foreground
+ Run in foreground (do not daemonize)
+ .TP
+-.B \-f " or " \-\-exports-file
++.B \-f export-file " or " \-\-exports-file export-file
+ This option specifies the exports file, listing the clients that this
+ server is prepared to serve and parameters to apply to each
+ such mount (see
+@@ -101,7 +101,7 @@ Display usage message.
+ Set the limit of the number of open file descriptors to num. The
+ default is to leave the limit unchanged.
+ .TP
+-.B \-N " or " \-\-no-nfs-version
++.B \-N mountd-version " or " \-\-no-nfs-version mountd-version
+ This option can be used to request that
+ .B rpc.mountd
+ do not offer certain versions of NFS. The current version of
+@@ -118,7 +118,7 @@ Don't advertise TCP for mount.
+ .B \-P
+ Ignored (compatibility with unfsd??).
+ .TP
+-.B \-p " or " \-\-port num
++.B \-p num " or " \-\-port num
+ Specifies the port number used for RPC listener sockets.
+ If this option is not specified,
+ .B rpc.mountd
+@@ -132,7 +132,7 @@ This option can be used to fix the port value of
+ listeners when NFS MOUNT requests must traverse a firewall
+ between clients and servers.
+ .TP
+-.B \-H " or " \-\-ha-callout prog
++.B \-H " prog or " \-\-ha-callout prog
+ Specify a high availability callout program.
+ This program receives callouts for all MOUNT and UNMOUNT requests.
+ This allows
+@@ -174,7 +174,7 @@ to perform a reverse lookup on each IP address and return that hostname instead.
+ Enabling this can have a substantial negative effect on performance
+ in some situations.
+ .TP
+-.BR "\-t N" " or " "\-\-num\-threads=N"
++.BR "\-t N" " or " "\-\-num\-threads=N" or " \-\-num\-threads N"
+ This option specifies the number of worker threads that rpc.mountd
+ spawns. The default is 1 thread, which is probably enough. More
+ threads are usually only needed for NFS servers which need to handle
+@@ -184,7 +184,7 @@ your DNS server is slow or unreliable.
+ .B \-u " or " \-\-no-udp
+ Don't advertise UDP for mounting
+ .TP
+-.B \-V " or " \-\-nfs-version
++.B \-V version " or " \-\-nfs-version version
+ This option can be used to request that
+ .B rpc.mountd
+ offer certain versions of NFS. The current version of
+diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c
+index 73d6a92..03e3c81 100644
+--- a/utils/nfsd/nfsd.c
++++ b/utils/nfsd/nfsd.c
+@@ -101,7 +101,7 @@ main(int argc, char **argv)
+ int count = NFSD_NPROC, c, i, error = 0, portnum = 0, fd, found_one;
+ char *p, *progname, *port, *rdma_port = NULL;
+ char **haddr = NULL;
+- unsigned int hcounter = 0;
++ int hcounter = 0;
+ int socket_up = 0;
+ unsigned int minorvers = 0;
+ unsigned int minorversset = 0;
+diff --git a/utils/nfsdcltrack/Makefile.am b/utils/nfsdcltrack/Makefile.am
+index a860ffb..7524295 100644
+--- a/utils/nfsdcltrack/Makefile.am
++++ b/utils/nfsdcltrack/Makefile.am
+@@ -1,5 +1,9 @@
+ ## Process this file with automake to produce Makefile.in
+
++# These binaries go in /sbin (not /usr/sbin), and that cannot be
++# overridden at config time. The kernel "knows" the /sbin name.
++sbindir = /sbin
++
+ man8_MANS = nfsdcltrack.man
+ EXTRA_DIST = $(man8_MANS)
+
+diff --git a/utils/statd/callback.c b/utils/statd/callback.c
+index d1cc139..bb7c590 100644
+--- a/utils/statd/callback.c
++++ b/utils/statd/callback.c
+@@ -10,11 +10,13 @@
+ #include <config.h>
+ #endif
+
++#include <unistd.h>
+ #include <netdb.h>
+
+ #include "rpcmisc.h"
+ #include "statd.h"
+ #include "notlist.h"
++#include "ha-callout.h"
+
+ /* Callback notify list. */
+ /* notify_list *cbnl = NULL; ... never used */
+@@ -87,6 +89,13 @@ sm_notify_1_svc(struct stat_chge *argp, struct svc_req *rqstp)
+ xlog(D_CALL, "Received SM_NOTIFY from %s, state: %d",
+ argp->mon_name, argp->state);
+
++ if (!statd_present_address(sap, ip_addr, sizeof(ip_addr))) {
++ xlog_warn("Unrecognized sender address");
++ return ((void *) &result);
++ }
++
++ ha_callout("sm-notify", argp->mon_name, ip_addr, argp->state);
++
+ /* quick check - don't bother if we're not monitoring anyone */
+ if (rtnl == NULL) {
+ xlog_warn("SM_NOTIFY from %s while not monitoring any hosts",
+@@ -94,11 +103,6 @@ sm_notify_1_svc(struct stat_chge *argp, struct svc_req *rqstp)
+ return ((void *) &result);
+ }
+
+- if (!statd_present_address(sap, ip_addr, sizeof(ip_addr))) {
+- xlog_warn("Unrecognized sender address");
+- return ((void *) &result);
+- }
+-
+ /* okir change: statd doesn't remove the remote host from its
+ * internal monitor list when receiving an SM_NOTIFY call from
+ * it. Lockd will want to continue monitoring the remote host
+diff --git a/utils/statd/start-statd b/utils/statd/start-statd
+index cde3583..dcdaf77 100644
+--- a/utils/statd/start-statd
++++ b/utils/statd/start-statd
+@@ -4,8 +4,8 @@
+ # /var/run/rpc.statd.pid).
+ # It should run statd with whatever flags are apropriate for this
+ # site.
+-PATH=/sbin:/usr/sbin
+-if systemctl start statd.service
++PATH="/sbin:/usr/sbin:/bin:/usr/bin"
++if systemctl start rpc-statd.service
+ then :
+ else
+ exec rpc.statd --no-notify
+diff --git a/utils/statd/statd.man b/utils/statd/statd.man
+index 896c2f8..1e5520c 100644
+--- a/utils/statd/statd.man
++++ b/utils/statd/statd.man
+@@ -346,7 +346,8 @@ points due to inactivity.
+ .SS High-availability callouts
+ .B rpc.statd
+ can exec a special callout program during processing of
+-successful SM_MON, SM_UNMON, and SM_UNMON_ALL requests.
++successful SM_MON, SM_UNMON, and SM_UNMON_ALL requests,
++or when it receives SM_NOTIFY.
+ Such a program may be used in High Availability NFS (HA-NFS)
+ environments to track lock state that may need to be migrated after
+ a system reboot.
+@@ -357,15 +358,26 @@ option.
+ The program is run with 3 arguments:
+ The first is either
+ .B add-client
+-or
+ .B del-client
++or
++.B sm-notify
+ depending on the reason for the callout.
+ The second is the
+ .I mon_name
+ of the monitored peer.
+ The third is the
+-.I caller_name
+-of the requesting lock manager.
++.I caller_name
++of the requesting lock manager for
++.B add-client
++or
++.B del-client
++, otherwise it is
++.I IP_address
++of the caller sending SM_NOTIFY.
++The forth is the
++.I state_value
++in the SM_NOTIFY request.
++
+ .SS IPv6 and TI-RPC support
+ TI-RPC is a pre-requisite for supporting NFS on IPv6.
+ If TI-RPC support is built into