[nfs-utils] Updated to latest upstream RC release: nfs-utils-1-2-9-rc6
Steve Dickson
steved at fedoraproject.org
Tue Sep 24 19:39:38 UTC 2013
commit 3936b52ffe14841433a76880b63ab99a85e1e464
Author: Steve Dickson <steved at redhat.com>
Date: Tue Sep 24 15:38:11 2013 -0400
Updated to latest upstream RC release: nfs-utils-1-2-9-rc6
Signed-off-by: Steve Dickson <steved at redhat.com>
nfs-utils-1.2.1-exp-subtree-warn-off.patch | 6 +-
nfs-utils.1.2.9-rc6.patch | 1597 ++++++++++++++++++++++++++++
nfs-utils.spec | 7 +-
3 files changed, 1605 insertions(+), 5 deletions(-)
---
diff --git a/nfs-utils-1.2.1-exp-subtree-warn-off.patch b/nfs-utils-1.2.1-exp-subtree-warn-off.patch
index ff60c7d..69c4cb5 100644
--- a/nfs-utils-1.2.1-exp-subtree-warn-off.patch
+++ b/nfs-utils-1.2.1-exp-subtree-warn-off.patch
@@ -1,7 +1,7 @@
diff -up nfs-utils-1.2.8/support/nfs/exports.c.orig nfs-utils-1.2.8/support/nfs/exports.c
---- nfs-utils-1.2.8/support/nfs/exports.c.orig 2013-09-18 15:34:18.655550000 -0400
-+++ nfs-utils-1.2.8/support/nfs/exports.c 2013-09-18 15:35:01.173808000 -0400
-@@ -505,7 +505,7 @@ void fix_pseudoflavor_flags(struct expor
+--- nfs-utils-1.2.8/support/nfs/exports.c.orig 2013-09-24 15:35:26.022548905 -0400
++++ nfs-utils-1.2.8/support/nfs/exports.c 2013-09-24 15:35:51.274547991 -0400
+@@ -508,7 +508,7 @@ void fix_pseudoflavor_flags(struct expor
static int
parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
{
diff --git a/nfs-utils.1.2.9-rc6.patch b/nfs-utils.1.2.9-rc6.patch
new file mode 100644
index 0000000..998c4b6
--- /dev/null
+++ b/nfs-utils.1.2.9-rc6.patch
@@ -0,0 +1,1597 @@
+diff --git a/support/include/conffile.h b/support/include/conffile.h
+index ce7aa21..05ea5d2 100644
+--- a/support/include/conffile.h
++++ b/support/include/conffile.h
+@@ -54,7 +54,7 @@ extern int conf_end(int, int);
+ extern void conf_free_list(struct conf_list *);
+ extern struct sockaddr *conf_get_address(char *, char *);
+ extern struct conf_list *conf_get_list(char *, char *);
+-extern struct conf_list *conf_get_tag_list(char *);
++extern struct conf_list *conf_get_tag_list(char *, char *);
+ extern int conf_get_num(char *, char *, int);
+ extern char *conf_get_str(char *, char *);
+ extern char *conf_get_section(char *, char *, char *);
+diff --git a/support/include/nfs/nfs.h b/support/include/nfs/nfs.h
+index 174c2dd..38db5b5 100644
+--- a/support/include/nfs/nfs.h
++++ b/support/include/nfs/nfs.h
+@@ -15,6 +15,10 @@
+ #define NFSD_MINVERS 2
+ #define NFSD_MAXVERS 4
+
++#define NFS4_MINMINOR 1
++#define NFS4_MAXMINOR 2
++#define NFS4_VERDEFAULT 0x1 /* minor verion 1 */
++
+ struct nfs_fh_len {
+ int fh_size;
+ u_int8_t fh_handle[NFS3_FHSIZE];
+@@ -52,6 +56,7 @@ struct nfs_fh_old {
+ #define NFSCTL_UDPISSET(_cltbits) ((_cltbits) & NFSCTL_UDPBIT)
+ #define NFSCTL_TCPISSET(_cltbits) ((_cltbits) & NFSCTL_TCPBIT)
+
++#define NFSCTL_VERDEFAULT (0xc) /* versions 3 and 4 */
+ #define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << ((_v) - 1)))
+ #define NFSCTL_UDPSET(_cltbits) ((_cltbits) |= NFSCTL_UDPBIT)
+ #define NFSCTL_TCPSET(_cltbits) ((_cltbits) |= NFSCTL_TCPBIT)
+diff --git a/support/include/nfsrpc.h b/support/include/nfsrpc.h
+index a0b80e1..1bfae7a 100644
+--- a/support/include/nfsrpc.h
++++ b/support/include/nfsrpc.h
+@@ -156,6 +156,11 @@ extern unsigned long nfs_pmap_getport(const struct sockaddr_in *,
+ const struct timeval *);
+
+ /*
++ * Use nfs_pmap_getport to see if statd is running locally
++ */
++extern int nfs_probe_statd(void);
++
++/*
+ * Contact a remote RPC service to discover whether it is responding
+ * to requests.
+ */
+diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
+index 5015e94..c3434d5 100644
+--- a/support/nfs/conffile.c
++++ b/support/nfs/conffile.c
+@@ -565,7 +565,7 @@ cleanup:
+ }
+
+ struct conf_list *
+-conf_get_tag_list(char *section)
++conf_get_tag_list(char *section, char *arg)
+ {
+ struct conf_list *list = 0;
+ struct conf_list_node *node;
+@@ -579,6 +579,8 @@ conf_get_tag_list(char *section)
+ cb = LIST_FIRST(&conf_bindings[conf_hash (section)]);
+ for (; cb; cb = LIST_NEXT(cb, link)) {
+ if (strcasecmp (section, cb->section) == 0) {
++ if (arg != NULL && strcasecmp(arg, cb->arg) != 0)
++ continue;
+ list->cnt++;
+ node = calloc(1, sizeof *node);
+ if (!node)
+diff --git a/support/nfs/exports.c b/support/nfs/exports.c
+index dea040f..d3160d3 100644
+--- a/support/nfs/exports.c
++++ b/support/nfs/exports.c
+@@ -63,6 +63,7 @@ static int parsesquash(char *list, int **idp, int *lenp, char **ep);
+ static int parsenum(char **cpp);
+ static void freesquash(void);
+ static void syntaxerr(char *msg);
++static struct flav_info *find_flavor(char *name);
+
+ void
+ setexportent(char *fname, char *type)
+@@ -196,11 +197,38 @@ getexportent(int fromkernel, int fromexports)
+ return ⅇ
+ }
+
++static const struct secinfo_flag_displaymap {
++ unsigned int flag;
++ const char *set;
++ const char *unset;
++} secinfo_flag_displaymap[] = {
++ { NFSEXP_READONLY, "ro", "rw" },
++ { NFSEXP_INSECURE_PORT, "insecure", "secure" },
++ { NFSEXP_ROOTSQUASH, "root_squash", "no_root_squash" },
++ { NFSEXP_ALLSQUASH, "all_squash", "no_all_squash" },
++ { 0, NULL, NULL }
++};
++
++static void secinfo_flags_show(FILE *fp, unsigned int flags, unsigned int mask)
++{
++ const struct secinfo_flag_displaymap *p;
++
++ for (p = &secinfo_flag_displaymap[0]; p->flag != 0; p++) {
++ if (!(mask & p->flag))
++ continue;
++ fprintf(fp, ",%s", (flags & p->flag) ? p->set : p->unset);
++ }
++}
++
+ void secinfo_show(FILE *fp, struct exportent *ep)
+ {
++ const struct export_features *ef;
+ struct sec_entry *p1, *p2;
+- int flags;
+
++ ef = get_export_features();
++
++ if (ep->e_secinfo[0].flav == NULL)
++ secinfo_addflavor(find_flavor("sys"), ep);
+ for (p1=ep->e_secinfo; p1->flav; p1=p2) {
+
+ fprintf(fp, ",sec=%s", p1->flav->flavour);
+@@ -208,12 +236,7 @@ void secinfo_show(FILE *fp, struct exportent *ep)
+ p2++) {
+ fprintf(fp, ":%s", p2->flav->flavour);
+ }
+- flags = p1->flags;
+- fprintf(fp, ",%s", (flags & NFSEXP_READONLY) ? "ro" : "rw");
+- fprintf(fp, ",%sroot_squash", (flags & NFSEXP_ROOTSQUASH)?
+- "" : "no_");
+- fprintf(fp, ",%sall_squash", (flags & NFSEXP_ALLSQUASH)?
+- "" : "no_");
++ secinfo_flags_show(fp, p1->flags, ef->secinfo_flags);
+ }
+ }
+
+@@ -643,8 +666,6 @@ bad_option:
+ cp++;
+ }
+
+- if (ep->e_secinfo[0].flav == NULL)
+- secinfo_addflavor(find_flavor("sys"), ep);
+ fix_pseudoflavor_flags(ep);
+ ep->e_squids = squids;
+ ep->e_sqgids = sqgids;
+diff --git a/support/nfs/getport.c b/support/nfs/getport.c
+index 3331ad4..081594c 100644
+--- a/support/nfs/getport.c
++++ b/support/nfs/getport.c
+@@ -1102,3 +1102,25 @@ unsigned long nfs_pmap_getport(const struct sockaddr_in *sin,
+
+ return port;
+ }
++
++static const char *nfs_ns_pgmtbl[] = {
++ "status",
++ NULL,
++};
++
++/*
++ * nfs_probe_statd - use nfs_pmap_getport to see if statd is running locally
++ *
++ * Returns non-zero if statd is running locally.
++ */
++int nfs_probe_statd(void)
++{
++ struct sockaddr_in addr = {
++ .sin_family = AF_INET,
++ .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
++ };
++ rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
++
++ return nfs_getport_ping((struct sockaddr *)(char *)&addr, sizeof(addr),
++ program, (rpcvers_t)1, IPPROTO_UDP);
++}
+diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
+index b95b71d..3f5fea5 100644
+--- a/tools/mountstats/mountstats.py
++++ b/tools/mountstats/mountstats.py
+@@ -53,7 +53,7 @@ class DeviceData:
+ if words[6].find('nfs') != -1:
+ self.__nfs_data['statvers'] = words[7]
+ elif words[0] == 'age:':
+- self.__nfs_data['age'] = long(words[1])
++ self.__nfs_data['age'] = int(words[1])
+ elif words[0] == 'opts:':
+ self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'caps:':
+@@ -91,12 +91,12 @@ class DeviceData:
+ self.__nfs_data['shortwrites'] = int(words[22])
+ self.__nfs_data['delay'] = int(words[23])
+ elif words[0] == 'bytes:':
+- self.__nfs_data['normalreadbytes'] = long(words[1])
+- self.__nfs_data['normalwritebytes'] = long(words[2])
+- self.__nfs_data['directreadbytes'] = long(words[3])
+- self.__nfs_data['directwritebytes'] = long(words[4])
+- self.__nfs_data['serverreadbytes'] = long(words[5])
+- self.__nfs_data['serverwritebytes'] = long(words[6])
++ self.__nfs_data['normalreadbytes'] = int(words[1])
++ self.__nfs_data['normalwritebytes'] = int(words[2])
++ self.__nfs_data['directreadbytes'] = int(words[3])
++ self.__nfs_data['directwritebytes'] = int(words[4])
++ self.__nfs_data['serverreadbytes'] = int(words[5])
++ self.__nfs_data['serverwritebytes'] = int(words[6])
+
+ def __parse_rpc_line(self, words):
+ if words[0] == 'RPC':
+@@ -110,8 +110,8 @@ class DeviceData:
+ self.__rpc_data['rpcsends'] = int(words[4])
+ self.__rpc_data['rpcreceives'] = int(words[5])
+ self.__rpc_data['badxids'] = int(words[6])
+- self.__rpc_data['inflightsends'] = long(words[7])
+- self.__rpc_data['backlogutil'] = long(words[8])
++ self.__rpc_data['inflightsends'] = int(words[7])
++ self.__rpc_data['backlogutil'] = int(words[8])
+ elif words[1] == 'tcp':
+ self.__rpc_data['port'] = words[2]
+ self.__rpc_data['bind_count'] = int(words[3])
+@@ -121,7 +121,7 @@ class DeviceData:
+ self.__rpc_data['rpcsends'] = int(words[7])
+ self.__rpc_data['rpcreceives'] = int(words[8])
+ self.__rpc_data['badxids'] = int(words[9])
+- self.__rpc_data['inflightsends'] = long(words[10])
++ self.__rpc_data['inflightsends'] = int(words[10])
+ self.__rpc_data['backlogutil'] = int(words[11])
+ elif words[1] == 'rdma':
+ self.__rpc_data['port'] = words[2]
+@@ -148,7 +148,7 @@ class DeviceData:
+ else:
+ op = words[0][:-1]
+ self.__rpc_data['ops'] += [op]
+- self.__rpc_data[op] = [long(word) for word in words[1:]]
++ self.__rpc_data[op] = [int(word) for word in words[1:]]
+
+ def parse_stats(self, lines):
+ """Turn a list of lines from a mount stat file into a
+@@ -179,81 +179,81 @@ class DeviceData:
+ def display_nfs_options(self):
+ """Pretty-print the NFS options
+ """
+- print 'Stats for %s mounted on %s:' % \
+- (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
+-
+- print ' NFS mount options: %s' % ','.join(self.__nfs_data['mountoptions'])
+- print ' NFS server capabilities: %s' % ','.join(self.__nfs_data['servercapabilities'])
+- if self.__nfs_data.has_key('nfsv4flags'):
+- print ' NFSv4 capability flags: %s' % ','.join(self.__nfs_data['nfsv4flags'])
+- if self.__nfs_data.has_key('pseudoflavor'):
+- print ' NFS security flavor: %d pseudoflavor: %d' % \
+- (self.__nfs_data['flavor'], self.__nfs_data['pseudoflavor'])
++ print('Stats for %s mounted on %s:' % \
++ (self.__nfs_data['export'], self.__nfs_data['mountpoint']))
++
++ print(' NFS mount options: %s' % ','.join(self.__nfs_data['mountoptions']))
++ print(' NFS server capabilities: %s' % ','.join(self.__nfs_data['servercapabilities']))
++ if 'nfsv4flags' in self.__nfs_data:
++ print(' NFSv4 capability flags: %s' % ','.join(self.__nfs_data['nfsv4flags']))
++ if 'pseudoflavor' in self.__nfs_data:
++ print(' NFS security flavor: %d pseudoflavor: %d' % \
++ (self.__nfs_data['flavor'], self.__nfs_data['pseudoflavor']))
+ else:
+- print ' NFS security flavor: %d' % self.__nfs_data['flavor']
++ print(' NFS security flavor: %d' % self.__nfs_data['flavor'])
+
+ def display_nfs_events(self):
+ """Pretty-print the NFS event counters
+ """
+- print
+- print 'Cache events:'
+- print ' data cache invalidated %d times' % self.__nfs_data['datainvalidates']
+- print ' attribute cache invalidated %d times' % self.__nfs_data['attrinvalidates']
+- print ' inodes synced %d times' % self.__nfs_data['syncinodes']
+- print
+- print 'VFS calls:'
+- print ' VFS requested %d inode revalidations' % self.__nfs_data['inoderevalidates']
+- print ' VFS requested %d dentry revalidations' % self.__nfs_data['dentryrevalidates']
+- print
+- print ' VFS called nfs_readdir() %d times' % self.__nfs_data['vfsreaddir']
+- print ' VFS called nfs_lookup() %d times' % self.__nfs_data['vfslookup']
+- print ' VFS called nfs_permission() %d times' % self.__nfs_data['vfspermission']
+- print ' VFS called nfs_file_open() %d times' % self.__nfs_data['vfsopen']
+- print ' VFS called nfs_file_flush() %d times' % self.__nfs_data['vfsflush']
+- print ' VFS called nfs_lock() %d times' % self.__nfs_data['vfslock']
+- print ' VFS called nfs_fsync() %d times' % self.__nfs_data['vfsfsync']
+- print ' VFS called nfs_file_release() %d times' % self.__nfs_data['vfsrelease']
+- print
+- print 'VM calls:'
+- print ' VFS called nfs_readpage() %d times' % self.__nfs_data['vfsreadpage']
+- print ' VFS called nfs_readpages() %d times' % self.__nfs_data['vfsreadpages']
+- print ' VFS called nfs_writepage() %d times' % self.__nfs_data['vfswritepage']
+- print ' VFS called nfs_writepages() %d times' % self.__nfs_data['vfswritepages']
+- print
+- print 'Generic NFS counters:'
+- print ' File size changing operations:'
+- print ' truncating SETATTRs: %d extending WRITEs: %d' % \
+- (self.__nfs_data['setattrtrunc'], self.__nfs_data['extendwrite'])
+- print ' %d silly renames' % self.__nfs_data['sillyrenames']
+- print ' short reads: %d short writes: %d' % \
+- (self.__nfs_data['shortreads'], self.__nfs_data['shortwrites'])
+- print ' NFSERR_DELAYs from server: %d' % self.__nfs_data['delay']
++ print()
++ print('Cache events:')
++ print(' data cache invalidated %d times' % self.__nfs_data['datainvalidates'])
++ print(' attribute cache invalidated %d times' % self.__nfs_data['attrinvalidates'])
++ print(' inodes synced %d times' % self.__nfs_data['syncinodes'])
++ print()
++ print('VFS calls:')
++ print(' VFS requested %d inode revalidations' % self.__nfs_data['inoderevalidates'])
++ print(' VFS requested %d dentry revalidations' % self.__nfs_data['dentryrevalidates'])
++ print()
++ print(' VFS called nfs_readdir() %d times' % self.__nfs_data['vfsreaddir'])
++ print(' VFS called nfs_lookup() %d times' % self.__nfs_data['vfslookup'])
++ print(' VFS called nfs_permission() %d times' % self.__nfs_data['vfspermission'])
++ print(' VFS called nfs_file_open() %d times' % self.__nfs_data['vfsopen'])
++ print(' VFS called nfs_file_flush() %d times' % self.__nfs_data['vfsflush'])
++ print(' VFS called nfs_lock() %d times' % self.__nfs_data['vfslock'])
++ print(' VFS called nfs_fsync() %d times' % self.__nfs_data['vfsfsync'])
++ print(' VFS called nfs_file_release() %d times' % self.__nfs_data['vfsrelease'])
++ print()
++ print('VM calls:')
++ print(' VFS called nfs_readpage() %d times' % self.__nfs_data['vfsreadpage'])
++ print(' VFS called nfs_readpages() %d times' % self.__nfs_data['vfsreadpages'])
++ print(' VFS called nfs_writepage() %d times' % self.__nfs_data['vfswritepage'])
++ print(' VFS called nfs_writepages() %d times' % self.__nfs_data['vfswritepages'])
++ print()
++ print('Generic NFS counters:')
++ print(' File size changing operations:')
++ print(' truncating SETATTRs: %d extending WRITEs: %d' % \
++ (self.__nfs_data['setattrtrunc'], self.__nfs_data['extendwrite']))
++ print(' %d silly renames' % self.__nfs_data['sillyrenames'])
++ print(' short reads: %d short writes: %d' % \
++ (self.__nfs_data['shortreads'], self.__nfs_data['shortwrites']))
++ print(' NFSERR_DELAYs from server: %d' % self.__nfs_data['delay'])
+
+ def display_nfs_bytes(self):
+ """Pretty-print the NFS event counters
+ """
+- print
+- print 'NFS byte counts:'
+- print ' applications read %d bytes via read(2)' % self.__nfs_data['normalreadbytes']
+- print ' applications wrote %d bytes via write(2)' % self.__nfs_data['normalwritebytes']
+- print ' applications read %d bytes via O_DIRECT read(2)' % self.__nfs_data['directreadbytes']
+- print ' applications wrote %d bytes via O_DIRECT write(2)' % self.__nfs_data['directwritebytes']
+- print ' client read %d bytes via NFS READ' % self.__nfs_data['serverreadbytes']
+- print ' client wrote %d bytes via NFS WRITE' % self.__nfs_data['serverwritebytes']
++ print()
++ print('NFS byte counts:')
++ print(' applications read %d bytes via read(2)' % self.__nfs_data['normalreadbytes'])
++ print(' applications wrote %d bytes via write(2)' % self.__nfs_data['normalwritebytes'])
++ print(' applications read %d bytes via O_DIRECT read(2)' % self.__nfs_data['directreadbytes'])
++ print(' applications wrote %d bytes via O_DIRECT write(2)' % self.__nfs_data['directwritebytes'])
++ print(' client read %d bytes via NFS READ' % self.__nfs_data['serverreadbytes'])
++ print(' client wrote %d bytes via NFS WRITE' % self.__nfs_data['serverwritebytes'])
+
+ def display_rpc_generic_stats(self):
+ """Pretty-print the generic RPC stats
+ """
+ sends = self.__rpc_data['rpcsends']
+
+- print
+- print 'RPC statistics:'
++ print()
++ print('RPC statistics:')
+
+- print ' %d RPC requests sent, %d RPC replies received (%d XIDs not found)' % \
+- (sends, self.__rpc_data['rpcreceives'], self.__rpc_data['badxids'])
++ print(' %d RPC requests sent, %d RPC replies received (%d XIDs not found)' % \
++ (sends, self.__rpc_data['rpcreceives'], self.__rpc_data['badxids']))
+ if sends != 0:
+- print ' average backlog queue length: %d' % \
+- (float(self.__rpc_data['backlogutil']) / sends)
++ print(' average backlog queue length: %d' % \
++ (float(self.__rpc_data['backlogutil']) / sends))
+
+ def display_rpc_op_stats(self):
+ """Pretty-print the per-op stats
+@@ -261,23 +261,23 @@ class DeviceData:
+ sends = self.__rpc_data['rpcsends']
+
+ # XXX: these should be sorted by 'count'
+- print
++ print()
+ for op in self.__rpc_data['ops']:
+ stats = self.__rpc_data[op]
+ count = stats[0]
+ retrans = stats[1] - count
+ if count != 0:
+- print '%s:' % op
+- print '\t%d ops (%d%%)' % \
+- (count, ((count * 100) / sends)),
+- print '\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)),
+- print '\t%d major timeouts' % stats[2]
+- print '\tavg bytes sent per op: %d\tavg bytes received per op: %d' % \
+- (stats[3] / count, stats[4] / count)
+- print '\tbacklog wait: %f' % (float(stats[5]) / count),
+- print '\tRTT: %f' % (float(stats[6]) / count),
+- print '\ttotal execute time: %f (milliseconds)' % \
+- (float(stats[7]) / count)
++ print('%s:' % op)
++ print('\t%d ops (%d%%)' % \
++ (count, ((count * 100) / sends)), end=' ')
++ print('\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)), end=' ')
++ print('\t%d major timeouts' % stats[2])
++ print('\tavg bytes sent per op: %d\tavg bytes received per op: %d' % \
++ (stats[3] / count, stats[4] / count))
++ print('\tbacklog wait: %f' % (float(stats[5]) / count), end=' ')
++ print('\tRTT: %f' % (float(stats[6]) / count), end=' ')
++ print('\ttotal execute time: %f (milliseconds)' % \
++ (float(stats[7]) / count))
+
+ def compare_iostats(self, old_stats):
+ """Return the difference between two sets of stats
+@@ -285,9 +285,9 @@ class DeviceData:
+ result = DeviceData()
+
+ # copy self into result
+- for key, value in self.__nfs_data.iteritems():
++ for key, value in self.__nfs_data.items():
+ result.__nfs_data[key] = value
+- for key, value in self.__rpc_data.iteritems():
++ for key, value in self.__rpc_data.items():
+ result.__rpc_data[key] = value
+
+ # compute the difference of each item in the list
+@@ -295,7 +295,7 @@ 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']
+@@ -312,17 +312,17 @@ class DeviceData:
+ if sample_time == 0:
+ sample_time = float(self.__nfs_data['age'])
+
+- print
+- print '%s mounted on %s:' % \
+- (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
++ print()
++ print('%s mounted on %s:' % \
++ (self.__nfs_data['export'], self.__nfs_data['mountpoint']))
+
+- print '\top/s\trpc bklog'
+- print '\t%.2f' % (sends / sample_time),
++ print('\top/s\trpc bklog')
++ print('\t%.2f' % (sends / sample_time), end=' ')
+ if sends != 0:
+- print '\t%.2f' % \
+- ((float(self.__rpc_data['backlogutil']) / sends) / sample_time)
++ print('\t%.2f' % \
++ ((float(self.__rpc_data['backlogutil']) / sends) / sample_time))
+ else:
+- print '\t0.00'
++ print('\t0.00')
+
+ # reads: ops/s, kB/s, avg rtt, and avg exe
+ # XXX: include avg xfer size and retransmits?
+@@ -332,15 +332,15 @@ class DeviceData:
+ rtt = float(read_rpc_stats[6])
+ exe = float(read_rpc_stats[7])
+
+- print '\treads:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)'
+- print '\t\t%.2f' % (ops / sample_time),
+- print '\t\t%.2f' % (kilobytes / sample_time),
++ print('\treads:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)')
++ print('\t\t%.2f' % (ops / sample_time), end=' ')
++ print('\t\t%.2f' % (kilobytes / sample_time), end=' ')
+ if ops != 0:
+- print '\t\t%.2f' % (rtt / ops),
+- print '\t\t%.2f' % (exe / ops)
++ print('\t\t%.2f' % (rtt / ops), end=' ')
++ print('\t\t%.2f' % (exe / ops))
+ else:
+- print '\t\t0.00',
+- print '\t\t0.00'
++ print('\t\t0.00', end=' ')
++ print('\t\t0.00')
+
+ # writes: ops/s, kB/s, avg rtt, and avg exe
+ # XXX: include avg xfer size and retransmits?
+@@ -350,15 +350,15 @@ class DeviceData:
+ rtt = float(write_rpc_stats[6])
+ exe = float(write_rpc_stats[7])
+
+- print '\twrites:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)'
+- print '\t\t%.2f' % (ops / sample_time),
+- print '\t\t%.2f' % (kilobytes / sample_time),
++ print('\twrites:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)')
++ print('\t\t%.2f' % (ops / sample_time), end=' ')
++ print('\t\t%.2f' % (kilobytes / sample_time), end=' ')
+ if ops != 0:
+- print '\t\t%.2f' % (rtt / ops),
+- print '\t\t%.2f' % (exe / ops)
++ print('\t\t%.2f' % (rtt / ops), end=' ')
++ print('\t\t%.2f' % (exe / ops))
+ else:
+- print '\t\t0.00',
+- print '\t\t0.00'
++ print('\t\t0.00', end=' ')
++ print('\t\t0.00')
+
+ def parse_stats_file(filename):
+ """pop the contents of a mountstats file into a dictionary,
+@@ -388,18 +388,18 @@ def parse_stats_file(filename):
+ return ms_dict
+
+ def print_mountstats_help(name):
+- print 'usage: %s [ options ] <mount point>' % name
+- print
+- print ' Version %s' % Mountstats_version
+- print
+- print ' Display NFS client per-mount statistics.'
+- print
+- print ' --version display the version of this command'
+- print ' --nfs display only the NFS statistics'
+- print ' --rpc display only the RPC statistics'
+- print ' --start sample and save statistics'
+- print ' --end resample statistics and compare them with saved'
+- print
++ print('usage: %s [ options ] <mount point>' % name)
++ print()
++ print(' Version %s' % Mountstats_version)
++ print()
++ print(' Display NFS client per-mount statistics.')
++ print()
++ print(' --version display the version of this command')
++ print(' --nfs display only the NFS statistics')
++ print(' --rpc display only the RPC statistics')
++ print(' --start sample and save statistics')
++ print(' --end resample statistics and compare them with saved')
++ print()
+
+ def mountstats_command():
+ """Mountstats command
+@@ -414,7 +414,7 @@ def mountstats_command():
+ return
+
+ if arg in ['-v', '--version', 'version']:
+- print '%s version %s' % (sys.argv[0], Mountstats_version)
++ print('%s version %s' % (sys.argv[0], Mountstats_version))
+ sys.exit(0)
+
+ if arg in ['-n', '--nfs']:
+@@ -426,10 +426,10 @@ def mountstats_command():
+ continue
+
+ if arg in ['-s', '--start']:
+- raise Exception, 'Sampling is not yet implemented'
++ raise Exception('Sampling is not yet implemented')
+
+ if arg in ['-e', '--end']:
+- raise Exception, 'Sampling is not yet implemented'
++ raise Exception('Sampling is not yet implemented')
+
+ if arg == sys.argv[0]:
+ continue
+@@ -448,14 +448,14 @@ def mountstats_command():
+
+ for mp in mountpoints:
+ if mp not in mountstats:
+- print 'Statistics for mount point %s not found' % mp
++ print('Statistics for mount point %s not found' % mp)
+ continue
+
+ stats = DeviceData()
+ stats.parse_stats(mountstats[mp])
+
+ if not stats.is_nfs_mountpoint():
+- print 'Mount point %s exists but is not an NFS mount' % mp
++ print('Mount point %s exists but is not an NFS mount' % mp)
+ continue
+
+ if nfs_only:
+@@ -472,37 +472,37 @@ def mountstats_command():
+ stats.display_rpc_op_stats()
+
+ def print_nfsstat_help(name):
+- print 'usage: %s [ options ]' % name
+- print
+- print ' Version %s' % Mountstats_version
+- print
+- print ' nfsstat-like program that uses NFS client per-mount statistics.'
+- print
++ print('usage: %s [ options ]' % name)
++ print()
++ print(' Version %s' % Mountstats_version)
++ print()
++ print(' nfsstat-like program that uses NFS client per-mount statistics.')
++ print()
+
+ def nfsstat_command():
+ print_nfsstat_help(prog)
+
+ def print_iostat_help(name):
+- print 'usage: %s [ <interval> [ <count> ] ] [ <mount point> ] ' % name
+- print
+- print ' Version %s' % Mountstats_version
+- print
+- print ' iostat-like program to display NFS client per-mount statistics.'
+- print
+- print ' The <interval> parameter specifies the amount of time in seconds between'
+- print ' each report. The first report contains statistics for the time since each'
+- print ' file system was mounted. Each subsequent report contains statistics'
+- print ' collected during the interval since the previous report.'
+- print
+- print ' If the <count> parameter is specified, the value of <count> determines the'
+- print ' number of reports generated at <interval> seconds apart. If the interval'
+- print ' parameter is specified without the <count> parameter, the command generates'
+- print ' reports continuously.'
+- print
+- print ' If one or more <mount point> names are specified, statistics for only these'
+- print ' mount points will be displayed. Otherwise, all NFS mount points on the'
+- print ' client are listed.'
+- print
++ print('usage: %s [ <interval> [ <count> ] ] [ <mount point> ] ' % name)
++ print()
++ print(' Version %s' % Mountstats_version)
++ print()
++ print(' iostat-like program to display NFS client per-mount statistics.')
++ print()
++ print(' The <interval> parameter specifies the amount of time in seconds between')
++ print(' each report. The first report contains statistics for the time since each')
++ print(' file system was mounted. Each subsequent report contains statistics')
++ print(' collected during the interval since the previous report.')
++ print()
++ print(' If the <count> parameter is specified, the value of <count> determines the')
++ print(' number of reports generated at <interval> seconds apart. If the interval')
++ print(' parameter is specified without the <count> parameter, the command generates')
++ print(' reports continuously.')
++ print()
++ print(' If one or more <mount point> names are specified, statistics for only these')
++ print(' mount points will be displayed. Otherwise, all NFS mount points on the')
++ print(' client are listed.')
++ print()
+
+ def print_iostat_summary(old, new, devices, time):
+ for device in devices:
+@@ -530,7 +530,7 @@ def iostat_command():
+ return
+
+ if arg in ['-v', '--version', 'version']:
+- print '%s version %s' % (sys.argv[0], Mountstats_version)
++ print('%s version %s' % (sys.argv[0], Mountstats_version))
+ return
+
+ if arg == sys.argv[0]:
+@@ -543,14 +543,14 @@ def iostat_command():
+ if interval > 0:
+ interval_seen = True
+ else:
+- print 'Illegal <interval> value'
++ print('Illegal <interval> value')
+ return
+ elif not count_seen:
+ count = int(arg)
+ if count > 0:
+ count_seen = True
+ else:
+- print 'Illegal <count> value'
++ print('Illegal <count> value')
+ return
+
+ # make certain devices contains only NFS mount points
+@@ -563,13 +563,13 @@ def iostat_command():
+ check += [device]
+ devices = check
+ else:
+- for device, descr in mountstats.iteritems():
++ for device, descr in mountstats.items():
+ stats = DeviceData()
+ stats.parse_stats(descr)
+ if stats.is_nfs_mountpoint():
+ devices += [device]
+ if len(devices) == 0:
+- print 'No NFS mount points were found'
++ print('No NFS mount points were found')
+ return
+
+ old_mountstats = None
+@@ -608,7 +608,7 @@ try:
+ elif prog == 'ms-iostat':
+ iostat_command()
+ except KeyboardInterrupt:
+- print 'Caught ^C... exiting'
++ print('Caught ^C... exiting')
+ sys.exit(1)
+
+ sys.exit(0)
+diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
+index dfbef87..341cdbf 100644
+--- a/tools/nfs-iostat/nfs-iostat.py
++++ b/tools/nfs-iostat/nfs-iostat.py
+@@ -95,7 +95,7 @@ class DeviceData:
+ if words[6] == 'nfs':
+ self.__nfs_data['statvers'] = words[7]
+ elif words[0] == 'age:':
+- self.__nfs_data['age'] = long(words[1])
++ self.__nfs_data['age'] = int(words[1])
+ elif words[0] == 'opts:':
+ self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'caps:':
+@@ -116,7 +116,7 @@ class DeviceData:
+ elif words[0] == 'bytes:':
+ i = 1
+ for key in NfsByteCounters:
+- self.__nfs_data[key] = long(words[i])
++ self.__nfs_data[key] = int(words[i])
+ i += 1
+
+ def __parse_rpc_line(self, words):
+@@ -131,8 +131,8 @@ class DeviceData:
+ self.__rpc_data['rpcsends'] = int(words[4])
+ self.__rpc_data['rpcreceives'] = int(words[5])
+ self.__rpc_data['badxids'] = int(words[6])
+- self.__rpc_data['inflightsends'] = long(words[7])
+- self.__rpc_data['backlogutil'] = long(words[8])
++ self.__rpc_data['inflightsends'] = int(words[7])
++ self.__rpc_data['backlogutil'] = int(words[8])
+ elif words[1] == 'tcp':
+ self.__rpc_data['port'] = words[2]
+ self.__rpc_data['bind_count'] = int(words[3])
+@@ -142,8 +142,8 @@ class DeviceData:
+ self.__rpc_data['rpcsends'] = int(words[7])
+ self.__rpc_data['rpcreceives'] = int(words[8])
+ self.__rpc_data['badxids'] = int(words[9])
+- self.__rpc_data['inflightsends'] = long(words[10])
+- self.__rpc_data['backlogutil'] = long(words[11])
++ self.__rpc_data['inflightsends'] = int(words[10])
++ self.__rpc_data['backlogutil'] = int(words[11])
+ elif words[1] == 'rdma':
+ self.__rpc_data['port'] = words[2]
+ self.__rpc_data['bind_count'] = int(words[3])
+@@ -169,7 +169,7 @@ class DeviceData:
+ else:
+ op = words[0][:-1]
+ self.__rpc_data['ops'] += [op]
+- self.__rpc_data[op] = [long(word) for word in words[1:]]
++ self.__rpc_data[op] = [int(word) for word in words[1:]]
+
+ def parse_stats(self, lines):
+ """Turn a list of lines from a mount stat file into a
+@@ -271,7 +271,7 @@ class DeviceData:
+ nfs_stats = self.__nfs_data
+ lookup_ops = self.__rpc_data['LOOKUP'][0]
+ readdir_ops = self.__rpc_data['READDIR'][0]
+- if self.__rpc_data.has_key('READDIRPLUS'):
++ if 'READDIRPLUS' in self.__rpc_data:
+ readdir_ops += self.__rpc_data['READDIRPLUS'][0]
+
+ dentry_revals = nfs_stats['dentryrevalidates']
+@@ -330,7 +330,7 @@ class DeviceData:
+ def __print_rpc_op_stats(self, op, sample_time):
+ """Print generic stats for one RPC op
+ """
+- if not self.__rpc_data.has_key(op):
++ if op not in self.__rpc_data:
+ return
+
+ rpc_stats = self.__rpc_data[op]
+@@ -353,14 +353,14 @@ class DeviceData:
+ exe_per_op = 0.0
+
+ op += ':'
+- print('%s' % op.lower().ljust(15))
++ 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))
+- print('\t%7.3f' % (kilobytes / sample_time))
+- print('\t%7.3f' % kb_per_op)
+- print(' %7d (%3.1f%%)' % (retrans, retrans_percent))
+- print('\t%7.3f' % rtt_per_op)
++ 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)
+
+ def ops(self, sample_time):
+@@ -392,7 +392,7 @@ class DeviceData:
+ print()
+
+ print(' op/s\t\trpc bklog')
+- print('%7.2f' % (sends / sample_time))
++ print('%7.2f' % (sends / sample_time), end='')
+ print('\t%7.2f' % backlog)
+
+ if which == 0:
+@@ -405,7 +405,7 @@ class DeviceData:
+ elif which == 2:
+ self.__print_rpc_op_stats('LOOKUP', sample_time)
+ self.__print_rpc_op_stats('READDIR', sample_time)
+- if self.__rpc_data.has_key('READDIRPLUS'):
++ if 'READDIRPLUS' in self.__rpc_data:
+ self.__print_rpc_op_stats('READDIRPLUS', sample_time)
+ self.__print_dir_cache_stats(sample_time)
+ elif which == 3:
+@@ -413,6 +413,8 @@ class DeviceData:
+ self.__print_rpc_op_stats('WRITE', sample_time)
+ self.__print_page_stats(sample_time)
+
++ sys.stdout.flush()
++
+ #
+ # Functions
+ #
+@@ -450,7 +452,7 @@ def print_iostat_summary(old, new, devices, time, options):
+ if old:
+ # Trim device list to only include intersection of old and new data,
+ # this addresses umounts due to autofs mountpoints
+- devicelist = filter(lambda x:x in devices,old)
++ devicelist = [x for x in old if x in devices]
+ else:
+ devicelist = devices
+
+diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
+index 9f79541..4331697 100644
+--- a/utils/exportfs/exportfs.c
++++ b/utils/exportfs/exportfs.c
+@@ -420,7 +420,7 @@ static int test_export(char *path, int with_fsid)
+ char buf[1024];
+ int fd, n;
+
+- sprintf(buf, "-test-client- %s 3 %d -1 -1 0\n",
++ sprintf(buf, "-test-client- %s 3 %d 65534 65534 0\n",
+ path,
+ with_fsid ? NFSEXP_FSID : 0);
+ fd = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY);
+diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
+index bc1de73..58c0f66 100644
+--- a/utils/exportfs/exports.man
++++ b/utils/exportfs/exports.man
+@@ -39,7 +39,7 @@ the export name using a backslash followed by the character code as three
+ octal digits.
+ .PP
+ To apply changes to this file, run
+-.BR exportfs \-ra
++.BR "exportfs \-ra"
+ or restart the NFS server.
+ .PP
+ .SS Machine Name Formats
+diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man
+index 1df75c5..ac13fd4 100644
+--- a/utils/gssd/gssd.man
++++ b/utils/gssd/gssd.man
+@@ -195,11 +195,28 @@ option when starting
+ .BR rpc.gssd .
+ .SH OPTIONS
+ .TP
+-.B -D
+-DNS Reverse lookups are not used for determining the
+-server names pass to GSSAPI. This option will reverses that and forces
+-the use of DNS Reverse resolution of the server's IP address to
+-retrieve the server name to use in GSAPI authentication.
++.B \-D
++The server name passed to GSSAPI for authentication is normally the
++name exactly as requested. e.g. for NFS
++it is the server name in the "servername:/path" mount request. Only if this
++servername appears to be an IP address (IPv4 or IPv6) or an
++unqualified name (no dots) will a reverse DNS lookup
++will be performed to get the canoncial server name.
++
++If
++.B \-D
++is present, a reverse DNS lookup will
++.I always
++be used, even if the server name looks like a canonical name. So it
++is needed if partially qualified, or non canonical names are regularly
++used.
++
++Using
++.B \-D
++can introduce a security vulnerability, so it is recommended that
++.B \-D
++not be used, and that canonical names always be used when requesting
++services.
+ .TP
+ .B -f
+ Runs
+diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
+index af1844c..e58c341 100644
+--- a/utils/gssd/gssd_proc.c
++++ b/utils/gssd/gssd_proc.c
+@@ -67,7 +67,6 @@
+ #include <errno.h>
+ #include <gssapi/gssapi.h>
+ #include <netdb.h>
+-#include <ctype.h>
+
+ #include "gssd.h"
+ #include "err_util.h"
+@@ -176,7 +175,6 @@ get_servername(const char *name, const struct sockaddr *sa, const char *addr)
+ char *hostname;
+ char hbuf[NI_MAXHOST];
+ unsigned char buf[sizeof(struct in6_addr)];
+- int servername = 0;
+
+ if (avoid_dns) {
+ /*
+@@ -184,15 +182,18 @@ get_servername(const char *name, const struct sockaddr *sa, const char *addr)
+ * If it is an IP address, do the DNS lookup otherwise
+ * skip the DNS lookup.
+ */
+- servername = 0;
+- if (strchr(name, '.') && inet_pton(AF_INET, name, buf) == 1)
+- servername = 1; /* IPv4 */
+- else if (strchr(name, ':') && inet_pton(AF_INET6, name, buf) == 1)
+- servername = 1; /* or IPv6 */
+-
+- if (servername) {
++ int is_fqdn = 1;
++ if (strchr(name, '.') == NULL)
++ is_fqdn = 0; /* local name */
++ else if (inet_pton(AF_INET, name, buf) == 1)
++ is_fqdn = 0; /* IPv4 address */
++ else if (inet_pton(AF_INET6, name, buf) == 1)
++ is_fqdn = 0; /* IPv6 addrss */
++
++ if (is_fqdn) {
+ return strdup(name);
+ }
++ /* Sorry, cannot avoid dns after all */
+ }
+
+ switch (sa->sa_family) {
+@@ -466,8 +467,9 @@ process_clnt_dir(char *dir, char *pdir)
+ }
+ sprintf(clp->dirname, "%s/%s", pdir, dir);
+ if ((clp->dir_fd = open(clp->dirname, O_RDONLY)) == -1) {
+- printerr(0, "ERROR: can't open %s: %s\n",
+- clp->dirname, strerror(errno));
++ if (errno != ENOENT)
++ printerr(0, "ERROR: can't open %s: %s\n",
++ clp->dirname, strerror(errno));
+ goto fail_destroy_client;
+ }
+ fcntl(clp->dir_fd, F_SETSIG, DNOTIFY_SIGNAL);
+@@ -523,7 +525,7 @@ update_old_clients(struct dirent **namelist, int size, char *pdir)
+ /* only compare entries in the global list that are from the
+ * same pipefs parent directory as "pdir"
+ */
+- if (strncmp(clp->dirname, pdir, strlen(pdir)) != 0) continue;
++ if (strcmp(clp->dirname, pdir) != 0) continue;
+
+ stillhere = 0;
+ for (i=0; i < size; i++) {
+@@ -820,6 +822,7 @@ set_port:
+ */
+ static int
+ create_auth_rpc_client(struct clnt_info *clp,
++ char *tgtname,
+ CLIENT **clnt_return,
+ AUTH **auth_return,
+ uid_t uid,
+@@ -924,14 +927,16 @@ create_auth_rpc_client(struct clnt_info *clp,
+ clnt_spcreateerror(rpc_errmsg));
+ goto out_fail;
+ }
++ if (!tgtname)
++ tgtname = clp->servicename;
+
+- printerr(2, "creating context with server %s\n", clp->servicename);
+- auth = authgss_create_default(rpc_clnt, clp->servicename, &sec);
++ printerr(2, "creating context with server %s\n", tgtname);
++ auth = authgss_create_default(rpc_clnt, tgtname, &sec);
+ if (!auth) {
+ /* Our caller should print appropriate message */
+ printerr(2, "WARNING: Failed to create krb5 context for "
+ "user with uid %d for server %s\n",
+- uid, clp->servername);
++ uid, tgtname);
+ goto out_fail;
+ }
+
+@@ -1013,7 +1018,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ /* Try first to acquire credentials directly via GSSAPI */
+ err = gssd_acquire_user_cred(uid, &gss_cred);
+ if (!err)
+- create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
++ create_resp = create_auth_rpc_client(clp, tgtname, &rpc_clnt, &auth, uid,
+ AUTHTYPE_KRB5, gss_cred);
+ /* if create_auth_rplc_client fails try the traditional method of
+ * trolling for credentials */
+@@ -1022,7 +1027,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ if (err == -EKEYEXPIRED)
+ downcall_err = -EKEYEXPIRED;
+ else if (!err)
+- create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
++ create_resp = create_auth_rpc_client(clp, tgtname, &rpc_clnt, &auth, uid,
+ AUTHTYPE_KRB5, GSS_C_NO_CREDENTIAL);
+ }
+ }
+@@ -1033,8 +1038,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ int success = 0;
+ do {
+ gssd_refresh_krb5_machine_credential(clp->servername,
+- NULL, service,
+- tgtname);
++ NULL, service);
+ /*
+ * Get a list of credential cache names and try each
+ * of them until one works or we've tried them all
+@@ -1047,7 +1051,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ }
+ for (ccname = credlist; ccname && *ccname; ccname++) {
+ gssd_setup_krb5_machine_gss_ccache(*ccname);
+- if ((create_auth_rpc_client(clp, &rpc_clnt,
++ if ((create_auth_rpc_client(clp, tgtname, &rpc_clnt,
+ &auth, uid,
+ AUTHTYPE_KRB5,
+ GSS_C_NO_CREDENTIAL)) == 0) {
+diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
+index 6275dd8..c6e52fd 100644
+--- a/utils/gssd/krb5_util.c
++++ b/utils/gssd/krb5_util.c
+@@ -231,7 +231,7 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
+ continue;
+ }
+ if (uid == 0 && !root_uses_machine_creds &&
+- strstr(namelist[i]->d_name, "_machine_")) {
++ strstr(namelist[i]->d_name, "machine_")) {
+ printerr(3, "CC '%s' not available to root\n",
+ statname);
+ free(namelist[i]);
+@@ -825,8 +825,10 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname,
+ myhostad[i+1] = 0;
+
+ retval = get_full_hostname(myhostname, myhostname, sizeof(myhostname));
+- if (retval)
+- goto out;
++ if (retval) {
++ /* Don't use myhostname */
++ myhostname[0] = 0;
++ }
+
+ code = krb5_get_default_realm(context, &default_realm);
+ if (code) {
+@@ -852,11 +854,19 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname,
+ }
+
+ /*
+- * Try the "appropriate" realm first, and if nothing found for that
+- * realm, try the default realm (if it hasn't already been tried).
++ * Make sure the preferred_realm, which may have been explicitly set
++ * on the command line, is tried first. If nothing is found go on with
++ * the host and local default realm (if that hasn't already been tried).
+ */
+ i = 0;
+ realm = realmnames[i];
++
++ if (strcmp (realm, preferred_realm) != 0) {
++ realm = preferred_realm;
++ /* resetting the realmnames index */
++ i = -1;
++ }
++
+ while (1) {
+ if (realm == NULL) {
+ tried_all = 1;
+@@ -883,6 +893,8 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname,
+ myhostad,
+ NULL);
+ } else {
++ if (!myhostname[0])
++ continue;
+ snprintf(spn, sizeof(spn), "%s/%s@%s",
+ svcnames[j], myhostname, realm);
+ code = krb5_build_principal_ext(context, &princ,
+@@ -1137,7 +1149,7 @@ gssd_get_krb5_machine_cred_list(char ***list)
+ if (ple->ccname) {
+ /* Make sure cred is up-to-date before returning it */
+ retval = gssd_refresh_krb5_machine_credential(NULL, ple,
+- NULL, NULL);
++ NULL);
+ if (retval)
+ continue;
+ if (i + 1 > listsize) {
+@@ -1228,15 +1240,14 @@ gssd_destroy_krb5_machine_creds(void)
+ int
+ gssd_refresh_krb5_machine_credential(char *hostname,
+ struct gssd_k5_kt_princ *ple,
+- char *service,
+- char *tgtname)
++ char *service)
+ {
+ krb5_error_code code = 0;
+ krb5_context context;
+ krb5_keytab kt = NULL;;
+ int retval = 0;
+ char *k5err = NULL;
+- const char *svcnames[5] = { "$", "root", "nfs", "host", NULL };
++ const char *svcnames[] = { "$", "root", "nfs", "host", NULL };
+
+ /*
+ * If a specific service name was specified, use it.
+@@ -1268,10 +1279,7 @@ gssd_refresh_krb5_machine_credential(char *hostname,
+ if (ple == NULL) {
+ krb5_keytab_entry kte;
+
+- if (tgtname == NULL)
+- tgtname = hostname;
+-
+- code = find_keytab_entry(context, kt, tgtname, &kte, svcnames);
++ code = find_keytab_entry(context, kt, hostname, &kte, svcnames);
+ if (code) {
+ printerr(0, "ERROR: %s: no usable keytab entry found "
+ "in keytab %s for connection with host %s\n",
+diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h
+index eed1294..3f0723e 100644
+--- a/utils/gssd/krb5_util.h
++++ b/utils/gssd/krb5_util.h
+@@ -31,8 +31,7 @@ void gssd_setup_krb5_machine_gss_ccache(char *servername);
+ void gssd_destroy_krb5_machine_creds(void);
+ int gssd_refresh_krb5_machine_credential(char *hostname,
+ struct gssd_k5_kt_princ *ple,
+- char *service,
+- char *tgtname);
++ char *service);
+ char *gssd_k5_err_msg(krb5_context context, krb5_error_code code);
+ void gssd_k5_get_default_realm(char **def_realm);
+
+diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
+index beba9c4..b6c6231 100644
+--- a/utils/idmapd/idmapd.c
++++ b/utils/idmapd/idmapd.c
+@@ -502,7 +502,7 @@ nfsdcb(int UNUSED(fd), short which, void *data)
+ struct idmap_client *ic = data;
+ struct idmap_msg im;
+ u_char buf[IDMAP_MAXMSGSZ + 1];
+- size_t len;
++ ssize_t len;
+ ssize_t bsiz;
+ char *bp, typebuf[IDMAP_MAXMSGSZ],
+ buf1[IDMAP_MAXMSGSZ], authbuf[IDMAP_MAXMSGSZ], *p;
+@@ -511,10 +511,14 @@ nfsdcb(int UNUSED(fd), short which, void *data)
+ if (which != EV_READ)
+ goto out;
+
+- if ((len = read(ic->ic_fd, buf, sizeof(buf))) <= 0) {
++ len = read(ic->ic_fd, buf, sizeof(buf));
++ if (len == 0)
++ /* No upcall to read; not necessarily a problem: */
++ return;
++ if (len < 0) {
+ xlog_warn("nfsdcb: read(%s) failed: errno %d (%s)",
+- ic->ic_path, len?errno:0,
+- len?strerror(errno):"End of File");
++ ic->ic_path, errno,
++ strerror(errno));
+ nfsdreopen_one(ic);
+ return;
+ }
+diff --git a/utils/mount/configfile.c b/utils/mount/configfile.c
+index 6f2ee75..68b9f93 100644
+--- a/utils/mount/configfile.c
++++ b/utils/mount/configfile.c
+@@ -73,6 +73,8 @@ struct mnt_alias {
+ };
+ int mnt_alias_sz = (sizeof(mnt_alias_tab)/sizeof(mnt_alias_tab[0]));
+
++static int strict;
++
+ /*
+ * See if the option is an alias, if so return the
+ * real mount option along with the argument type.
+@@ -286,7 +288,7 @@ conf_parse_mntopts(char *section, char *arg, char *opts)
+ char *nvalue, *ptr;
+ int argtype;
+
+- list = conf_get_tag_list(section);
++ list = conf_get_tag_list(section, arg);
+ TAILQ_FOREACH(node, &list->fields, link) {
+ /*
+ * Do not overwrite options if already exists
+@@ -310,7 +312,15 @@ conf_parse_mntopts(char *section, char *arg, char *opts)
+ if (strcasecmp(value, "false") == 0) {
+ if (argtype != MNT_NOARG)
+ snprintf(buf, BUFSIZ, "no%s", field);
++ else if (strcasecmp(field, "bg") == 0)
++ snprintf(buf, BUFSIZ, "fg");
++ else if (strcasecmp(field, "fg") == 0)
++ snprintf(buf, BUFSIZ, "bg");
++ else if (strcasecmp(field, "sloppy") == 0)
++ strict = 1;
+ } else if (strcasecmp(value, "true") == 0) {
++ if ((strcasecmp(field, "sloppy") == 0) && strict)
++ continue;
+ snprintf(buf, BUFSIZ, "%s", field);
+ } else {
+ nvalue = strdup(value);
+@@ -345,6 +355,7 @@ char *conf_get_mntopts(char *spec, char *mount_point,
+ char *ptr, *server, *config_opts;
+ int optlen = 0;
+
++ strict = 0;
+ SLIST_INIT(&head);
+ list_size = 0;
+ /*
+diff --git a/utils/mount/network.c b/utils/mount/network.c
+index 4be48cd..e2cdcaf 100644
+--- a/utils/mount/network.c
++++ b/utils/mount/network.c
+@@ -65,11 +65,6 @@ extern int nfs_mount_data_version;
+ extern char *progname;
+ extern int verbose;
+
+-static const char *nfs_ns_pgmtbl[] = {
+- "status",
+- NULL,
+-};
+-
+ static const char *nfs_mnt_pgmtbl[] = {
+ "mount",
+ "mountd",
+@@ -761,18 +756,6 @@ int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
+ &nfs_server->pmap);
+ }
+
+-static int nfs_probe_statd(void)
+-{
+- struct sockaddr_in addr = {
+- .sin_family = AF_INET,
+- .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
+- };
+- rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
+-
+- return nfs_getport_ping(SAFE_SOCKADDR(&addr), sizeof(addr),
+- program, (rpcvers_t)1, IPPROTO_UDP);
+-}
+-
+ /**
+ * start_statd - attempt to start rpc.statd
+ *
+diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
+index a8ec46c..2a42b93 100644
+--- a/utils/mount/nfs.man
++++ b/utils/mount/nfs.man
+@@ -84,6 +84,20 @@ in
+ .SS "Options supported by all versions"
+ These options are valid to use with any NFS version.
+ .TP 1.5i
++.BI nfsvers= n
++The NFS protocol version number used to contact the server's NFS service.
++If the server does not support the requested version, the mount request
++fails.
++If this option is not specified, the client negotiates a suitable version
++with
++the server, trying version 4 first, version 3 second, and version 2 last.
++.TP 1.5i
++.BI vers= n
++This option is an alternative to the
++.B nfsvers
++option.
++It is included for compatibility with other operating systems
++.TP 1.5i
+ .BR soft " / " hard
+ Determines the recovery behavior of the NFS client
+ after an NFS request times out.
+@@ -621,18 +635,6 @@ Using this option ensures that
+ reports the proper maximum component length to applications
+ in such cases.
+ .TP 1.5i
+-.BI nfsvers= n
+-The NFS protocol version number used to contact the server's NFS service.
+-If the server does not support the requested version, the mount request fails.
+-If this option is not specified, the client negotiates a suitable version with
+-the server, trying version 4 first, version 3 second, and version 2 last.
+-.TP 1.5i
+-.BI vers= n
+-This option is an alternative to the
+-.B nfsvers
+-option.
+-It is included for compatibility with other operating systems.
+-.TP 1.5i
+ .BR lock " / " nolock
+ Selects whether to use the NLM sideband protocol to lock files on the server.
+ If neither option is specified (or if
+diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
+index 737927c..517aa62 100644
+--- a/utils/mountd/cache.c
++++ b/utils/mountd/cache.c
+@@ -347,20 +347,26 @@ static char *next_mnt(void **v, char *p)
+
+ static int is_subdirectory(char *child, char *parent)
+ {
++ /* Check is child is strictly a subdirectory of
++ * parent or a more distant descendant.
++ */
+ size_t l = strlen(parent);
+
+- if (strcmp(parent, "/") == 0)
++ if (strcmp(parent, "/") == 0 && child[1] != 0)
+ return 1;
+
+- return strcmp(child, parent) == 0
+- || (strncmp(child, parent, l) == 0 && child[l] == '/');
++ return (strncmp(child, parent, l) == 0 && child[l] == '/');
+ }
+
+ static int path_matches(nfs_export *exp, char *path)
+ {
+- if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
+- return is_subdirectory(path, exp->m_export.e_path);
+- return strcmp(path, exp->m_export.e_path) == 0;
++ /* Does the path match the export? I.e. is it an
++ * exact match, or does the export have CROSSMOUNT, and path
++ * is a descendant?
++ */
++ return strcmp(path, exp->m_export.e_path) == 0
++ || ((exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
++ && is_subdirectory(path, exp->m_export.e_path));
+ }
+
+ static int
+@@ -369,15 +375,13 @@ export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
+ return path_matches(exp, path) && client_matches(exp, dom, ai);
+ }
+
+-/* True iff e1 is a child of e2 and e2 has crossmnt set: */
++/* True iff e1 is a child of e2 (or descendant) and e2 has crossmnt set: */
+ static bool subexport(struct exportent *e1, struct exportent *e2)
+ {
+ char *p1 = e1->e_path, *p2 = e2->e_path;
+- size_t l2 = strlen(p2);
+
+ return e2->e_flags & NFSEXP_CROSSMOUNT
+- && strncmp(p1, p2, l2) == 0
+- && p1[l2] == '/';
++ && is_subdirectory(p1, p2);
+ }
+
+ struct parsed_fsid {
+diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c
+index e87c0a9..6db92f0 100644
+--- a/utils/nfsd/nfsd.c
++++ b/utils/nfsd/nfsd.c
+@@ -99,8 +99,8 @@ main(int argc, char **argv)
+ char *p, *progname, *port;
+ char *haddr = NULL;
+ int socket_up = 0;
+- int minorvers41 = 0; /* nfsv4 minor version */
+- unsigned int versbits = NFSCTL_ALLBITS;
++ int minorvers = NFS4_VERDEFAULT; /* nfsv4 minor version */
++ unsigned int versbits = NFSCTL_VERDEFAULT;
+ unsigned int protobits = NFSCTL_ALLBITS;
+ unsigned int proto4 = 0;
+ unsigned int proto6 = 0;
+@@ -160,11 +160,11 @@ main(int argc, char **argv)
+ case 4:
+ if (*p == '.') {
+ int i = atoi(p+1);
+- if (i != 1) {
++ if (i > 2) {
+ fprintf(stderr, "%s: unsupported minor version\n", optarg);
+ exit(1);
+ }
+- minorvers41 = -1;
++ NFSCTL_VERUNSET(minorvers, i);
+ break;
+ }
+ case 3:
+@@ -181,11 +181,11 @@ main(int argc, char **argv)
+ case 4:
+ if (*p == '.') {
+ int i = atoi(p+1);
+- if (i != 1) {
++ if (i > 2) {
+ fprintf(stderr, "%s: unsupported minor version\n", optarg);
+ exit(1);
+ }
+- minorvers41 = 1;
++ NFSCTL_VERSET(minorvers, i);
+ break;
+ }
+ case 3:
+@@ -282,7 +282,7 @@ main(int argc, char **argv)
+ * registered with rpcbind. Note that on older kernels w/o the right
+ * interfaces, these are a no-op.
+ */
+- nfssvc_setvers(versbits, minorvers41);
++ nfssvc_setvers(versbits, minorvers);
+
+ error = nfssvc_set_sockets(AF_INET, proto4, haddr, port);
+ if (!error)
+diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c
+index 683008e..8b85846 100644
+--- a/utils/nfsd/nfssvc.c
++++ b/utils/nfsd/nfssvc.c
+@@ -269,7 +269,7 @@ nfssvc_set_sockets(const int family, const unsigned int protobits,
+ }
+
+ void
+-nfssvc_setvers(unsigned int ctlbits, int minorvers41)
++nfssvc_setvers(unsigned int ctlbits, int minorvers)
+ {
+ int fd, n, off;
+ char *ptr;
+@@ -280,9 +280,12 @@ nfssvc_setvers(unsigned int ctlbits, int minorvers41)
+ if (fd < 0)
+ return;
+
+- if (minorvers41)
+- off += snprintf(ptr+off, sizeof(buf) - off, "%c4.1",
+- minorvers41 > 0 ? '+' : '-');
++ for (n = NFS4_MINMINOR; n <= NFS4_MAXMINOR; n++) {
++ if (NFSCTL_VERISSET(minorvers, n))
++ off += snprintf(ptr+off, sizeof(buf) - off, "+4.%d ", n);
++ else
++ off += snprintf(ptr+off, sizeof(buf) - off, "-4.%d ", n);
++ }
+ for (n = NFSD_MINVERS; n <= NFSD_MAXVERS; n++) {
+ if (NFSCTL_VERISSET(ctlbits, n))
+ off += snprintf(ptr+off, sizeof(buf) - off, "+%d ", n);
+diff --git a/utils/nfsdcltrack/nfsdcltrack.man b/utils/nfsdcltrack/nfsdcltrack.man
+index 47007df..6940788 100644
+--- a/utils/nfsdcltrack/nfsdcltrack.man
++++ b/utils/nfsdcltrack/nfsdcltrack.man
+@@ -1,53 +1,3 @@
+-.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
+-.\"
+-.\" Standard preamble:
+-.\" ========================================================================
+-.de Sp \" Vertical space (when we can't use .PP)
+-.if t .sp .5v
+-.if n .sp
+-..
+-.de Vb \" Begin verbatim text
+-.ft CW
+-.nf
+-.ne \\$1
+-..
+-.de Ve \" End verbatim text
+-.ft R
+-.fi
+-..
+-.\" Set up some character translations and predefined strings. \*(-- will
+-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+-.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+-.\" nothing in troff, for use with C<>.
+-.tr \(*W-
+-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+-.ie n \{\
+-. ds -- \(*W-
+-. ds PI pi
+-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+-. ds L" ""
+-. ds R" ""
+-. ds C` ""
+-. ds C' ""
+-'br\}
+-.el\{\
+-. ds -- \|\(em\|
+-. ds PI \(*p
+-. ds L" ``
+-. ds R" ''
+-'br\}
+-.\"
+-.\" Escape single quotes in literal strings from groff's Unicode transform.
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\"
+-.\" If the F register is turned on, we'll generate index entries on stderr for
+-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+-.\" entries marked with X<> in POD. Of course, you'll have to process the
+-.\" output yourself in some meaningful fashion.
+ .ie \nF \{\
+ . de IX
+ . tm Index:\\$1\t\\n%\t"\\$2"
+@@ -59,70 +9,6 @@
+ . de IX
+ ..
+ .\}
+-.\"
+-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+-.\" Fear. Run. Save yourself. No user-serviceable parts.
+-. \" fudge factors for nroff and troff
+-.if n \{\
+-. ds #H 0
+-. ds #V .8m
+-. ds #F .3m
+-. ds #[ \f1
+-. ds #] \fP
+-.\}
+-.if t \{\
+-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+-. ds #V .6m
+-. ds #F 0
+-. ds #[ \&
+-. ds #] \&
+-.\}
+-. \" simple accents for nroff and troff
+-.if n \{\
+-. ds ' \&
+-. ds ` \&
+-. ds ^ \&
+-. ds , \&
+-. ds ~ ~
+-. ds /
+-.\}
+-.if t \{\
+-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+-.\}
+-. \" troff and (daisy-wheel) nroff accents
+-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+-.ds ae a\h'-(\w'a'u*4/10)'e
+-.ds Ae A\h'-(\w'A'u*4/10)'E
+-. \" corrections for vroff
+-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+-. \" for low resolution devices (crt and lpr)
+-.if \n(.H>23 .if \n(.V>19 \
+-\{\
+-. ds : e
+-. ds 8 ss
+-. ds o a
+-. ds d- d\h'-1'\(ga
+-. ds D- D\h'-1'\(hy
+-. ds th \o'bp'
+-. ds Th \o'LP'
+-. ds ae ae
+-. ds Ae AE
+-.\}
+-.rm #[ #] #H #V #F C
+-.\" ========================================================================
+-.\"
+ .IX Title "NFSDCLTRACK 8"
+ .TH NFSDCLTRACK 8 "2012-10-24" "" ""
+ .\" For nroff, turn off justification. Always turn off hyphenation; it makes
+diff --git a/utils/nfsidmap/Makefile.am b/utils/nfsidmap/Makefile.am
+index c0675c4..737a219 100644
+--- a/utils/nfsidmap/Makefile.am
++++ b/utils/nfsidmap/Makefile.am
+@@ -1,9 +1,10 @@
+ ## Process this file with automake to produce Makefile.in
+
+ man8_MANS = nfsidmap.man
+-
+ sbin_PROGRAMS = nfsidmap
++
+ nfsidmap_SOURCES = nfsidmap.c
+ nfsidmap_LDADD = $(LIBNFSIDMAP) -lkeyutils ../../support/nfs/libnfs.a
+
+ MAINTAINERCLEANFILES = Makefile.in
++EXTRA_DIST = id_resolver.conf
+diff --git a/utils/nfsidmap/id_resolver.conf b/utils/nfsidmap/id_resolver.conf
+new file mode 100644
+index 0000000..2c156c6
+--- /dev/null
++++ b/utils/nfsidmap/id_resolver.conf
+@@ -0,0 +1 @@
++create id_resolver * * /usr/sbin/nfsidmap -t 600 %k %d
+diff --git a/utils/statd/statd.c b/utils/statd/statd.c
+index 652546c..8c51bcc 100644
+--- a/utils/statd/statd.c
++++ b/utils/statd/statd.c
+@@ -28,6 +28,7 @@
+
+ #include "statd.h"
+ #include "nfslib.h"
++#include "nfsrpc.h"
+ #include "nsm.h"
+
+ /* Socket operations */
+@@ -237,6 +238,12 @@ int main (int argc, char **argv)
+ /* Set hostname */
+ MY_NAME = NULL;
+
++ /* Refuse to start if another statd is running */
++ if (nfs_probe_statd()) {
++ fprintf(stderr, "Statd service already running!\n");
++ exit(1);
++ }
++
+ /* Process command line switches */
+ while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:L", longopts, NULL)) != EOF) {
+ switch (arg) {
diff --git a/nfs-utils.spec b/nfs-utils.spec
index c9db9db..9fae510 100644
--- a/nfs-utils.spec
+++ b/nfs-utils.spec
@@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
Name: nfs-utils
URL: http://sourceforge.net/projects/nfs
Version: 1.2.8
-Release: 5.0%{?dist}
+Release: 6.0%{?dist}
Epoch: 1
# group all 32bit related archs
@@ -36,7 +36,7 @@ Source51: nfs-server.preconfig
Source52: nfs-server.postconfig
%define nfs_configs %{SOURCE50} %{SOURCE51} %{SOURCE52}
-Patch001: nfs-utils.1.2.9-rc4.patch
+Patch001: nfs-utils.1.2.9-rc6.patch
Patch100: nfs-utils-1.2.1-statdpath-man.patch
Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch
@@ -312,6 +312,9 @@ fi
/sbin/umount.nfs4
%changelog
+* Tue Sep 24 2013 Steve Dickson <steved at redhat.com> 1.2.8-6.0
+- Updated to latest upstream RC release: nfs-utils-1-2-9-rc6
+
* Wed Sep 18 2013 Steve Dickson <steved at redhat.com> 1.2.8-5.0
- Updated to latest upstream RC release: nfs-utils-1-2-9-rc5
More information about the scm-commits
mailing list