Imported Upstream version 1.2.4 upstream/1.2.4
authorLuk Claes <luk@debian.org>
Sat, 9 Jul 2011 10:20:38 +0000 (12:20 +0200)
committerLuk Claes <luk@debian.org>
Sat, 9 Jul 2011 10:20:38 +0000 (12:20 +0200)
72 files changed:
.gitignore
ChangeLog
aclocal/keyutils.m4 [new file with mode: 0644]
aclocal/libnfsidmap.m4
configure.ac
support/export/client.c
support/export/export.c
support/export/hostname.c
support/export/nfsctl.c
support/include/exportfs.h
support/include/misc.h
support/include/nfslib.h
support/include/rpcmisc.h
support/nfs/Makefile.am
support/nfs/atomicio.c [new file with mode: 0644]
support/nfs/conffile.c
support/nfs/exports.c
support/nfs/nfs_mntent.c
support/nfs/rpcdispatch.c
support/nfs/strlcat.c [new file with mode: 0644]
support/nfs/strlcpy.c [new file with mode: 0644]
support/nfs/svc_create.c
support/nsm/file.c
tests/nsm_client/nsm_client.c
utils/Makefile.am
utils/exportfs/exportfs.c
utils/exportfs/exportfs.man
utils/exportfs/exports.man
utils/gssd/Makefile.am
utils/gssd/gss_util.c
utils/gssd/gssd.man
utils/gssd/gssd_proc.c
utils/gssd/krb5_util.c
utils/gssd/svcgssd.c
utils/gssd/svcgssd.man
utils/gssd/svcgssd_krb5.c [new file with mode: 0644]
utils/gssd/svcgssd_krb5.h [new file with mode: 0644]
utils/gssd/svcgssd_proc.c
utils/idmapd/Makefile.am
utils/idmapd/atomicio.c [deleted file]
utils/idmapd/idmapd.c
utils/idmapd/strlcat.c [deleted file]
utils/idmapd/strlcpy.c [deleted file]
utils/mount/Makefile.am
utils/mount/fstab.c
utils/mount/mount.c
utils/mount/mount_config.h
utils/mount/mount_constants.h
utils/mount/mount_libmount.c [new file with mode: 0644]
utils/mount/network.c
utils/mount/network.h
utils/mount/nfs.man
utils/mount/nfsumount.c
utils/mount/parse_opt.c
utils/mount/stropts.c
utils/mount/utils.c [new file with mode: 0644]
utils/mount/utils.h [new file with mode: 0644]
utils/mount/version.h
utils/mountd/cache.c
utils/mountd/mountd.c
utils/mountd/mountd.man
utils/mountd/rmtab.c
utils/mountd/v4root.c
utils/nfsd/nfssvc.c
utils/nfsidmap/Makefile.am [new file with mode: 0644]
utils/nfsidmap/nfsidmap.c [new file with mode: 0644]
utils/nfsidmap/nfsidmap.man [new file with mode: 0644]
utils/nfsstat/nfsstat.c
utils/nfsstat/nfsstat.man
utils/statd/hostname.c
utils/statd/sm-notify.c
utils/statd/statd.man

index 4bff9e3..f5b5cf0 100644 (file)
@@ -64,6 +64,7 @@ tests/nsm_client/nlm_sm_inter.h
 tests/nsm_client/nlm_sm_inter_clnt.c
 tests/nsm_client/nlm_sm_inter_svc.c
 tests/nsm_client/nlm_sm_inter_xdr.c
+utils/nfsidmap/nfsidmap
 # cscope database files
 cscope.*
 # generic editor backup et al
index efef742..062ed67 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-commit 3030aded70e616cdeac4223785754b86a33b587d
-Author: Eberhard Kuemmerle <e.kuemmerle@fz-juelich.de>
-Date:   Mon Sep 27 13:24:48 2010 -0400
+commit 684cf4a5e0e84a1367690d7ecf4882cbdf4f3228
+Author: Prem Karat <prem.karat@linux.vnet.ibm.com>
+Date:   Thu Jun 30 07:29:20 2011 -0400
 
-    Added the -p <principal> flag to the svcgssd manpage
+    mount.nfs: Fix for the bug in v1.2.4 that breaks mount.nfs
     
-    Signed-off-by:  Eberhard Kuemmerle <E.Kuemmerle@fz-juelich.de>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 6cc96cada639a823961d5d8a136cbcdc8b8952b8
-Author: Eberhard Kuemmerle <e.kuemmerle@fz-juelich.de>
-Date:   Mon Sep 27 13:16:23 2010 -0400
-
-    svcgssd: Adding a <-p principal> flag
-    
-    Allow the principal that is used to get the machines creds definable
-    on the command like with the new '-p <principal>'. This is useful
-    in cluster environments.
+    commit 30ebf047 failed to include these changes that breaks mount.nfs.
+    mount.nfs will continue to work fine with these changes
     
-    Signed-off-by:  Eberhard Kuemmerle <E.Kuemmerle@fz-juelich.de>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 837796686ad8f9178c7b6855ada728a53ae511e3
-Author: David Lecorfe <dlecorfec@gmail.com>
-Date:   Mon Sep 27 13:29:31 2010 -0400
+commit 057d2add27d1e05fed3ae7206ee043b6c1fda45a
+Author: NeilBrown <neilb@suse.de>
+Date:   Tue Jun 28 13:24:33 2011 -0400
 
-    nfs-iostat.py: don't wait for an extra interval when given a count
-    
-    If I invoke the tool with an interval of 10 and a count of 2, it will:
-    - show the summary
-    - sleep 10s
-    - show the stats for the last 10s
-    - sleep 10s
-    - exit
+    Do not compile unnecessary files when the libmount code is enable
     
-    Signed-off-by: David Lecorfe <dlecorfec@gmail.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit eaa588a137b0b2f38aa9e9c542635a222e51ee48
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 10:16:34 2010 -0400
+commit 30ebf04700654deddbf5f57d95e84ec69cea8610
+Author: Prem Karat <prem.karat@linux.vnet.ibm.com>
+Date:   Tue Jun 28 11:53:40 2011 -0400
 
-    nfsd: Enable IPv6 support in rpc.nfsd again.
+    mount.nfs: Don't hard code source and destination
     
-    Revert commit b2a3cd59 so that rpc.nfsd can create IPv6 listener
-    sockets for the kernel.
+    Currently souce and destination parameters should be passed as first and
+    second paramter while using mount.nfs. This patch allows them to be passed
+    anywhere while mounting.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Current functionality is
+       mount.nfs source destn -o <options>
+    This patch will allow to do this
+       mount.nfs -o <options> source destn
+               or
+       mount.nfs -o <options> source -o <options> destn
+    
+    Signed-off-by: Prem Karat <prem.karat@linux.vnet.ibm.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit c18e9a780f376b868e62b75abe64b0fd9915ada5
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 10:14:34 2010 -0400
+commit b3e190c4adfc9ec47567c968bd000d282d07b05e
+Author: NeilBrown <neilb@suse.de>
+Date:   Tue Jun 28 11:36:31 2011 -0400
 
-    mountd: Update mountd/exportfs man pages to reflect IPv6 changes
+    mount: improve signal management when locking mtab
     
-    Document IPv6 support in rpc.mountd and exportfs, and clarify existing
-    language in the man page.
+    As mount.nfs can run setuid it must be careful about how the user can
+    interact with in.  In particular it needs to ensure it does not
+    respond badly to any signals that the user might be able to generate.
     
-    Clean up: Use bold consistently for program names, and italics
-    consistently for file names.  Use "rpc.mountd" consistently as the
-    name of the mountd daemon.
+    This is particularly an issue while updating /etc/mtab (when that is
+    not linked to /proc/mounts).  If the user can generate a signal which
+    kills mount.nfs while /etc/mtab is locked, then it will leave the file
+    locked, and could possibly corrupt mtab (particularly if 'ulimit 1'
+    was previously issued).
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 7e454e03131f56872639fe7b62b726479b22c087
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 10:13:39 2010 -0400
-
-    mountd: Use MNT status values instead of NFSERR
+    Currently lock_mtab does set some handlers for signals, but not
+    enough.  It arranges for every signal up to (but not including)
+    SIGCHLD to cause mount.nfs to unlock mdadm promptly exit ... even if
+    the default behaviour would be to ignore the signal.  SIGALRM is
+    handled specially, and signals after SIGCHLD are left with their
+    default behaviour.  This includes for example SIGXFSZ which can be
+    generated by the user running "ulimit 1".
     
-    Clean up:  The MNT protocol has its own enum type defining error
-    status values.  While the values can be the same as the NFSERR enum
-    type on some systems, it's not guaranteed to be true everywhere.
+    So: change this so that some signals are left unchanged, SIGALRM is
+    handled as required, and all signals that the user can generate are
+    explicitly ignored.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    The remainder still cause mount.nfs to print a message, unlock mtab, and
+    exit.
+    
+    Signed-off-by: NeilBrown <neilb@suse.de>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit ef32b76ae37926faacaf4b8121eba638567c4692
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 10:11:18 2010 -0400
+commit a99b7846e2abec5e26ab6b764b921d79559e0a0f
+Author: J. Bruce Fields <bfields@redhat.com>
+Date:   Mon Jun 27 12:31:07 2011 -0400
 
-    mountd: Fix up version and usage messages
+    mountd: move fsidtype-specific code to helpers
     
-    Clean up: rpc.mountd is no longer known as kmountd.  Use the program's
-    basename rather than the full pathname for the usage message.  Display
-    a version message at start up similar to statd's.
+    Now we can move these big switch statements into helper functions.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 2c15cf2963367dee7106964c38ab7b1e30ba347d
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 10:09:49 2010 -0400
+commit e6559fd0b7b63f5d152d33d598dc74d78df30ecb
+Author: J. Bruce Fields <bfields@redhat.com>
+Date:   Mon Jun 27 12:30:36 2011 -0400
 
-    mountd: Unregister mountd if my_svc_run() returns
+    mountd: gather fsid information into one struct
     
-    Fix a long standing bug: when my_svc_run() returns, mountd should
-    unregister itself with the local rpcbind so that it can subsequently
-    start cleanly.
+    A large part of nfsd_fh() is concerned with extracting
+    fsid-type-specific information from the fsid, then matching that
+    information with information from the export list and the filesystem.
     
-    Log a more helpful error message in this case.
+    Moving all that information into one struct will allow some further
+    simplifications.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit b551b1fd0052de9b8c674b30c39d9f2a1e9d79cc
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 10:09:10 2010 -0400
+commit 13a0a61d037f2cc09e7997a96ce5822b9317883b
+Author: J. Bruce Fields <bfields@redhat.com>
+Date:   Mon Jun 27 12:29:51 2011 -0400
 
-    mountd: Support TI-RPC mountd listener
+    mountd: prefer explicit subexports over crossmnt parents
     
-    If TI-RPC is available, use it to create mountd's svc listener.  If
-    not, use the old function, rpc_init(), to create mountd's listener.
+    If a parent is exported with crossmnt, and if a child is also explicitly
+    exported, then both exports could potentially produce matches in this
+    loop; that isn't a bug.
     
-    IPv6 can be supported if TI-RPC is available.  In this case,
-    /etc/netconfig is searched to determine which transports to advertise.
+    Instead of warning and ignoring the second match we find, we should
+    instead prefer whichever export is deeper in the tree, so that
+    children's options can override those of their parents.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Reported-by: Olga Kornievskaia <aglo@citi.umich.edu>
+    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit c5571da8e92f87fc9ec6e8aa8075c69497361c87
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 10:06:35 2010 -0400
+commit f8d26c1db9a260597828685c7f62e1b29e78285f
+Author: Jeff Layton <jlayton@redhat.com>
+Date:   Wed Jun 22 15:52:55 2011 -0400
 
-    mountd: Make NFS version checks more strict
-    
-    Ensure users and programmers specify NFS version numbers correctly.
-    This also makes the next patch more clean.
+    manpage: add section on character class matches to exports(5)
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Jeff Layton <jlayton@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 05f93b531d59df6e976d9b40c97b51546524040a
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Sep 27 09:50:11 2010 -0400
+commit cb6676aea5bcfcbeaf868e53177eff51f4efe9a8
+Author: James Pearson <james-p@moving-picture.com>
+Date:   Wed Jun 22 15:51:47 2011 -0400
 
-    nfs-utils: Fix source code character encoding
-    
-    Minor clean up.
-    
-    Most modern Linux distributions set UTF-8 locales.  Standardize the
-    character encoding of source files on UTF-8, to squelch vim com-
-    plaints.
+    nfs-utils: remove possibly false statement from exports.man
     
-    I probably missed a few spots.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 5341111d4b34bcd1b1263d5ed215cbe375aa9314
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Sep 27 09:35:26 2010 -0400
-
-    libnfs.a: Remove support/nfs/fstab.c
+    A very minor change suggested by J. Bruce Fields <bfields@fieldses.org>
+    to remove the statement that exporting to a single host or IP address is
+    the "most common format" - as it probably isn't.
     
+    Signed-off-by: James Pearson <james-p@moving-picture.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 72ae199db4be7bf0092e15adaa8a43ce2434bf9f
+commit 7d71ff8e3825a7f8c2d5c9b5b9344e95e7aa1392
 Author: Jeff Layton <jlayton@redhat.com>
-Date:   Thu Sep 16 14:34:39 2010 -0400
+Date:   Wed Jun 22 15:51:02 2011 -0400
 
-    rpc.nfsd: mount up nfsdfs is it doesn't appear to be mounted yet
+    manpage: add info about IPv6 configuration to exports(5)
     
-    There's a bit of a chicken and egg problem when nfsd is run the first
-    time. On Fedora/RHEL at least, /proc/fs/nfsd is mounted up whenever nfsd
-    is plugged in via a modprobe.conf "install" directive.
-    
-    If someone runs rpc.nfsd without plugging in nfsd.ko first,
-    /proc/fs/nfsd won't be mounted and rpc.nfsd will end up using the legacy
-    nfsctl interface. After that, nfsd will be plugged in and subsequent
-    rpc.nfsd invocations will use that instead.
-    
-    This is a problem as some nfsd command-line options are ignored when the
-    legacy interface is used. It'll also be a problem for people who want
-    IPv6 enabled servers. The upshot is that we really don't want to use the
-    legacy interface unless there is no other option.
-    
-    To avoid this situation, have rpc.nfsd check to see if the "threads"
-    file is already present. If it's not, then make an attempt to mount
-    /proc/fs/nfsd.  This is a "best-effort" sort of thing, however so we
-    just ignore the return code from the mount attempt and fall back to
-    using nfsctl() if it fails.
+    The parts of the exports(5) manpage that discuss IP addressing neglect
+    IPv6 configuration. Update to include info on how to export to IPv6
+    subnets and addresses, and add a line demonstrating that to the EXAMPLE
+    section.
     
     Signed-off-by: Jeff Layton <jlayton@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 63afb96b9d36e72782ad25ca496896029a9d9061
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 14:25:52 2010 -0400
+commit 545ea1098089d6396d5a70111ec231c4de967faa
+Author: Benny Halevy <benny@tonian.com>
+Date:   Wed Jun 22 15:44:17 2011 -0400
 
-    libexport.a: Enable IPv6 support in hostname.c
+    nfsstat: reorder nfs4 stats for 2.6.39
     
-    If --enable-ipv6 is specified when building nfs-utils, libexport's
-    host_foo() helpers can now return both IPv4 and IPv6 addresses.
-    
-    This means IPv6 presentation addresses and IPv6 DNS resolution
-    results are handled properly in the mountd cache and /etc/exports,
-    but does not yet enable IPv6 mountd listeners.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Benny Halevy <benny@tonian.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit d901e329e380a2adc22783b1b241e414aa24cf51
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 14:21:48 2010 -0400
+commit c7ce7a4674ad446bee4dd3baf90155ce6b216816
+Author: Mi Jinlong <mijinlong@cn.fujitsu.com>
+Date:   Wed Jun 22 15:41:27 2011 -0400
 
-    mountd: Ensure cache downcall can handle IPv6 addresses
+    libexport.a: fix using bad index for loop at cltsetup()
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    In cltsetup(), when checking the address, use clp's naddr for index,
+    instead of  cltarg's naddr, which it's always zero there.
+    
+    Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 1ba28ec59f39de0bc4953b42556d847efbb508eb
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 14:21:08 2010 -0400
+commit b50ad13298b3e9519a9bdecb8c146c9ecf39cef8
+Author: Jeff Layton <jlayton@redhat.com>
+Date:   Wed Jun 22 14:51:38 2011 -0400
 
-    mountd: Handle IPv6 addresses in kernel auth_unix_ip upcalls
+    nfs: fix host_reliable_addrinfo
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit ffe8c9a084fec4fdd3acfcf4b36fbe434d297b82
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 14:19:19 2010 -0400
-
-    mountd: clean up cache API
-    
-    Clean up: Squelch compiler warnings and document public parts of
-    cache API.
-    
-    cache.c: At top level:
-    cache.c:67: warning: no previous prototype for auth_unix_ip
-    cache.c:123: warning: no previous prototype for auth_unix_gid
-    cache.c:217: warning: no previous prototype for get_uuid
-    cache.c:247: warning: no previous prototype for uuid_by_path
-    cache.c:326: warning: no previous prototype for nfsd_fh
-    cache.c:745: warning: no previous prototype for nfsd_export
-    cache.c:820: warning: no previous prototype for cache_open
-    cache.c:832: warning: no previous prototype for cache_set_fd
-    cache.c:841: warning: no previous prototype for
-    cache_process_req
-    cache.c:921: warning: no previous prototype for cache_export
-    cache.c:953: warning: no previous prototype for
-    cache_get_filehandle
+    According to Neil Brown:
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 6f189dae5eb38800c8ae3e2d5c098d11fb44d7d5
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 14:17:08 2010 -0400
-
-    exportfs: Enable IPv6 support in matchhostname()
+        The point of the word 'reliable' is to check that the name we get
+        really does belong to the host in question - ie that both the
+        forward and reverse maps agree.
     
-    To gain IPv6 support in matchhostname(), simply replace the socket
-    address comparison helpers with the generic versions that can handle
-    IPv4 and IPv6.
+        But the new code doesn't do that check at all.  Rather it simply
+        maps the address to a name, then discards the address and maps the
+        name back to a list of addresses and uses that list of addresses as
+        "where the request came from" for permission checking.
     
-    host_addrinfo() (called by matchhostname()) returns IPv6 addresses
-    only if IPv6 support is enabled.
+    This bug is exploitable via the following scenario and could allow an
+    attacker access to data that they shouldn't be able to access.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 10a6b17d3588647ab5e1ee81ba40f1ce12a5184d
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 13:54:21 2010 -0400
-
-    mountd: Support IPv6 in mountlist_list()
+        Suppose you export a filesystem to some subnet or FQDN and also to a
+        wildcard or netgroup, and I know the details of this (maybe
+        showmount -e tells me) Suppose further that I can get IP packets to
+        your server..
     
-    Replace inet_aton(3) and gethostbyaddr(3) calls in mountlist_list()
-    with calls to the new host_foo() DNS helpers.
+        Then I create a reverse mapping for my ipaddress to a domain that I
+        own, say "black.hat.org", and a forward mapping from that domain to
+        my IP address, and one of your IP addresses.
     
-    The new functions will support IPv6 without additional changes, once
-    IPv6 is enabled in the generic hostname helpers.
+        Then I try to mount your filesystem.  The IP address gets correctly
+        mapped to "black.hat.org" and then mapped to both my IP address and
+        your IP address.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 76209cdbe989ee4cdfbf489f2695ac779457e763
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 13:51:51 2010 -0400
-
-    mountd: Handle memory exhaustion in mountlist_list()
+        Then you search through all of your exports and find that one of the
+        addresses: yours - is allowed to access the filesystem.
     
-    I'm about to replace inet_aton(3)/gethostbyaddr(3) with
-    host_pton()/host_canonname() in mountlist_list().
+        So you create an export based on the addrinfo you have which allows
+        my IP address the same access as your IP address.
     
-    Since host_canonname() returns a string allocated with strdup(3)
-    instead of xstrdup(), mountlist_list() must now deal with memory
-    exhaustion properly.
+    Fix this by instead using the forward lookup of the hostname just to
+    verify that the original address is in the list. Then do a numeric
+    lookup using the address and stick the hostname in the ai_canonname.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Reviewed-by: NeilBrown <neilb@suse.de>
+    Signed-off-by: Jeff Layton <jlayton@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit a8348c2c48d45f991995707fa22a2fa441aaa907
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 13:48:38 2010 -0400
+commit 7235a2164aabfd8dba1f7e1577047bda45053db0
+Author: James Pearson <james-p@moving-picture.com>
+Date:   Tue Jun 7 16:25:13 2011 -0400
 
-    mountd: Add mountlist_freeall()
+    exports: Clearly Defining Exports Priorities
     
-    I'm about to add a second bit of logic that needs to free all
-    mountlist records, so introduce a helper for freeing them.
+    Added some verbiage to the exports(5) man page
+    that clearly explains the precedence around
+    how exports will work with regard to netgroups.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 454aea5dad83ca75f3154ff12ecff39169703e69
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 13:46:26 2010 -0400
+commit a36f2437caffb23c68fdc0900544d59198bd52b6
+Author: Neil Brown <neilb@suse.de>
+Date:   Tue Jun 7 13:18:55 2011 -0400
 
-    mountd: support IPv6 in mountlist_del_all()
+    Document "-n" for svcgssd
     
-    Replace IPv4-specific code in the mountlist_del_all() path with code
-    that is address family agnostic.
+    The svcgssd man page doesn't mention the "-n" flag.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: NeilBrown <neilb@suse.de>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 4210d6f0c9cad57907877bf1e5d32ebe4a27bf17
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 13:44:02 2010 -0400
+commit 40aed2c3fb5164195a9975ae7f15ebd4b992839d
+Author: Pavel Shilovsky <piastry@etersoft.ru>
+Date:   Tue Jun 7 13:18:13 2011 -0400
 
-    mountd: Support IPv6 in mountd's svc routines
+    mountd: Fix missing varialble assignment in auth_unix_gid
     
-    Replace IPv4-specific code with use of our generic hostname helpers
-    in the routines that handle incoming MNT RPC requests.
-    
-    These functions will support IPv6 without additional changes, once
-    IPv6 is enabled in the generic hostname helpers.
-    
-    As part of this update, I've modified all of mountd's _svc routines
-    to use a debug message format that is consistent with statd.  It may
-    be overkill for some of these; if so we can pull them out later.
+    When we get into auth_unix_gid at the second time, groups_len
+    is not 0 and ngroups variable leave as 0. Then we use ngroups
+    in getgrouplist that fails in this case. This patch fixes it.
     
+    Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit f35762f959cc5f29ad7817f8b7968e3792132651
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 13:39:39 2010 -0400
+commit 8935933dedcd820c2fb3dddff8b79fd5841dc217
+Author: Benny Halevy <bhalevy@panasas.com>
+Date:   Mon May 23 08:37:17 2011 -0400
 
-    mountd: add IPv6 support in auth_authenticate()
+    nfsstat: reorder nfs4 stats for 2.6.38 and up
     
-    Make the entire auth_authenticate() code path address-family agnostic.
+    match order in 2.6.38, 2.6.39 (-rc3) and development tree
+    while at it, get rid of obsolete ds_write and ds_commit
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Benny Halevy <bhalevy@panasas.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 29b8a7700129d9768e3e2d94c81eec9f84ba8691
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 09:32:52 2010 -0400
+commit 27dcd8a775024160e741cce53e4a402eaac3501d
+Author: NeilBrown <neilb@suse.de>
+Date:   Mon May 23 08:23:51 2011 -0400
 
-    libnfs.a: Fix API for getfh() & friends
-    
-    This is more of a clean-up than a behavioral change.
-    
-    POSIX requires that a "struct sockaddr" is the same size as a "struct
-    sockaddr_in".  Therefore, a variable or field of type "struct sockaddr"
-    cannot contain an AF_INET6 address.  However, "struct sockaddr *" is
-    often used to reference a generic (ie non-address family specific)
-    socket address, generating some confusion about this.
+    supress socket error when address family is not supported
     
-    The nfsctl_arg struct uses a struct sockaddr (not a pointer) to pass
-    the client's IP address to the kernel.  This means the legacy nfsctl()
-    kernel API can never support IPv6.  Fortunately for us, this legacy
-    interface was replaced by a text-based cache interface a few years
-    back.  We don't need to support non-AF_INET addresses here.
+    From: Suresh Jayaraman <sjayaraman@suse.de>
     
-    The getfh() functions in nfs-utils provide a handy C API for the
-    kernel's nfsctl interface.  The getfh() functions still take a struct
-    sockaddr *, though, and that can imply that a non-IPv4 address can be
-    passed via this API.  To make it abundantly clear that only IPv4
-    addresses can be used with this interface, change the synopses of
-    getfh() and friends to take a struct sockaddr_in * instead of a struct
-    sockaddr * .
+    It was observed that when ipv6 module was not loaded and cannot be auto-loaded,
+    when starting NFS server, the following error occurs:
+       "rpc.nfsd: unable to create inet6 TCP socket: errno 97 (Address
+       family not supported by protocol)"
     
-    This makes these functions conform with other places in mountd and
-    exportfs that already grok the difference between a struct sockaddr
-    and a struct sockaddr_in.
+    This is obviously a true message, but does not represent an "error" when ipv6
+    is not enabled.  Rather, it is an expected condition.  As such, it can be
+    confusing / misleading / distracting to display it in this scenario.
     
-    While we're here...
+    This patch instead of throwing error when a socket call fails with
+    EAFNOSUPPORT, makes it as a NOTICE.
     
-    Introduce some nice documenting comments for the get_fh() functions,
-    and...
-    
-    Since mountd will support IPv6 in the near future, assert that the
-    family of client addresses passed to this API is indeed AF_INET, in
-    order to prevent non-AF_INET addresses from ever being passed to the
-    legacy nfsctl() interface.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
+    Signed-off-by: Neil Brown <neilb@suse.de>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit a88c279992f4b63e3dcaac9930e300fd4bb03dd7
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 07:28:18 2010 -0400
+commit 7a802337bfc92d0b30fe94dbd0fa231990a26161
+Author: NeilBrown <neilb@suse.de>
+Date:   Mon May 23 08:19:57 2011 -0400
 
-    mount.nfs: Don't do anything fancy if this is a remount
-    
-    We don't want to append "vers=4" or perform any negotiation if the
-    "remount" mount option was specified.  It will just end in tears.
+    Remove risk of nfs_addmntent corrupting mtab
     
-    This attempts to address
+    nfs_addmntent is used to append directly to /etc/mtab.
+    If the write partially fail, e.g. due to RLIMIT_FSIZE,
+    truncate back to original size and return an error.
     
-      https://qa.mandriva.com/show_bug.cgi?id=60311
+    See also https://bugzilla.redhat.com/show_bug.cgi?id=697975
+    (CVE-2011-1749) CVE-2011-1749 nfs-utils: mount.nfs fails to anticipate RLIMIT_FSIZE
     
-    and
-    
-      https://bugzilla.linux-nfs.org/show_bug.cgi?id=187
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: NeilBrown <neilb@suse.de>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 6f73daf5a5711dc0620f7d43c61c4fd57c0d3f80
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 16 07:26:07 2010 -0400
+commit 56f537535190d034039570bafd9a0de71b79b8f1
+Author: Ben Myers <bpm@sgi.com>
+Date:   Mon May 23 08:07:00 2011 -0400
 
-    mount.nfs: Refactor mount version and protocol autonegotiation
-    
-    Clean up.
-    
-    I'm beginning to agree with Bruce and Steve's assessment that the
-    fallthrough switch case in nfs_try_mount() is more difficult to read
-    and understand than it needs to be.  The logic that manages
-    negotiating NFS version and protocol settings is getting more complex
-    over time anyway.
-    
-    So let's split the autonegotiation piece out of nfs_try_mount().
+    exportfs: getexportent interprets -test-client- as default options
     
-    We can reduce indenting, and use cleaner switch-based logic.  Also,
-    adding more comments can only help.
+    With commit 1374c3861abdc66f3a1410e26cc85f86760b51dd Neil added a
+    -test-client- export to test the exportability of filesystems when exportfs
+    is run.  When using the old cache controls (i.e. /proc/fs/nfsd is not
+    mounted) exportfs will read /proc/fs/nfs/exports to process existing
+    exports and find these test client entries.  The dash at the beginning of
+    -test-client- will be cause getexportent to look for default options in the
+    rest of the string, which test-client- will not match:
     
-    Neil also suggested replacing the pre-call "errno = 0" trick.  The
-    lower-level functions may try to mount several times (given a list of
-    addresses to try).  errno could be set by any of those.  The mount
-    request will succeed at some point, and "success" is returned, but
-    errno is still set to some non-zero value.
+    exportfs: /proc/fs/nfs/exports:1: unknown keyword "test-client-(rw"
     
-    The kernel version check in nfs_try_mount() is more or less loop
-    invariant: it's impossible for the result of that test to change
-    between retries.  So we should be able to safely move it to the logic
-    that sets the initial value of mi->version.
+    This patch resolves that problem (as Steve suggested) by not processing any
+    default options if we are reading the list of existing exports from the
+    kernel.  Default options are converted to individual exports by exportfs so
+    the kernel won't have any regardless.
     
-    This patch is not supposed to cause a behavioral change.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Ben Myers <bpm@sgi.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 64bf8db367fd43e80dd135b460afc157808647fa
-Author: Bian Naimeng <biannm@cn.fujitsu.com>
-Date:   Thu Sep 16 07:12:47 2010 -0400
+commit c8e802c036a3f0fcd4481dae8b3ec09fb71f4118
+Author: Jim Rees <rees@umich.edu>
+Date:   Wed May 18 12:42:02 2011 -0400
 
-    rpc.idmapd: Type of idmap client should be defined by ic_id not ic_clid.
+    Removed compilation warnings from mountd/cache.c
     
-    The type of idmap_client is defined by idmap_client.ic_id for nfs,
-    so nfsd should have the same style.
+    Commit 5604b35a6 introduced a number of missing initializer
+    warnings that were missed. This patch removes those warnings.
     
-    Signed-off-by: Bian Naimeng <biannm@cn.fujitsu.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 7f77ef90ad52eced1552efc2242e063aa4501ddc
-Author: Benny Halevy <bhalevy@panasas.com>
-Date:   Tue Jul 20 08:40:34 2010 +0300
-
-    nfsstat: add release_lockowner to client stats
-    
-    Signed-off-by: Benny Halevy <bhalevy@panasas.com>
-
-commit bf6da0a22d971364dae25ec2f62c01fbd2960f07
+commit 68f7938c85258a8c54b13169dcdeae61cc1bf286
 Author: Steve Dickson <steved@redhat.com>
-Date:   Thu Sep 9 10:47:32 2010 -0400
+Date:   Tue Apr 26 13:32:35 2011 -0400
 
-    Cleaned up a warning from commit 44f09b7
+    nfsstat: Output headings mislabled
+    
+    The badclnt and badauth headers were reversed
+    when the server side rpc stats (-s -o rpc) were
+    displayed.
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 911630538580cdaaee1c37cdf1a8b35b8ed6b23f
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed Sep 8 13:28:24 2010 -0400
+commit 2e4a7e9b50a641dc8640a5dd911ee4a2f0b2c073
+Author: Steve Dickson <steved@redhat.com>
+Date:   Tue Apr 19 12:31:30 2011 -0400
 
-    mount.nfs: Prepare way for "vers=4,rdma" mounts
+    rpc.svcgssd: Segmentation fault on error
     
-    At some point, when the kernel starts to support "vers=4,rdma" mounts,
-    we will want the mount.nfs command to pass "vers=4,rdma" mounts
-    instead of rejecting them.
+    Commit 544ed73d introduced a regression that caused
+    rpc.svcgssd to seg fault on "Wrong principal in request"
+    errors in gss_accept_sec_context()
     
-    Assuming that the kernel will reject these today with EPROTONOSUPPORT,
-    that would cause the version fallback logic to go to "vers=3,rdma"
-    automatically.  So the extra check we have now is not needed anyway.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit f99d1b8e8768ab96b51bed52f21a626ac9a4797f
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed Sep 8 13:27:31 2010 -0400
+commit 5604b35a61e22930873ffc4e9971002f578e7978
+Author: Sean Finney <sean.finney@sonyericsson.com>
+Date:   Tue Apr 19 11:04:35 2011 -0400
 
-    mount.nfs: Support an "rdma" mount option
+    nfs-utils: Increase the stdio file buffer size for procfs files
     
-    The kernel NFS client's mount option parser recognizes a stand-alone
-    "rdma" mount option, similar to the legacy "udp" and "tcp" options.
+    Previously, when writing to /proc/net/rpc/*/channel, if a cache line
+    were larger than the default buffer size (likely 1024 bytes), mountd
+    and svcgssd would split writes into a number of buffer-sized writes.
+    Each of these writes would get an EINVAL error back from the kernel
+    procfs handle (it expects line-oriented input and does not account for
+    multiple/split writes), and no cache update would occur.
     
-    The mount.nfs command text-based mount option parser used to pass
-    "rdma" straight to the kernel, but since we've started handling MNT in
-    the kernel instead of in user space, "rdma" on the command line has
-    not worked.
+    When such behavior occurs, NFS clients depending on mountd to finish
+    the cache operation would block/hang, or receive EPERM, depending on
+    the context of the operation.  This is likely to happen if a user is a
+    member of a large (~100-200) number of groups.
     
-    Until now, no-one has noticed, especially since an "rdma" mount option
-    isn't documented in nfs(5).
+    Instead, every fopen() on the procfs files in question is followed by
+    a call to setvbuf(), using a per-file dedicated buffer of
+    RPC_CHAN_BUF_SIZE length.
     
-    Support "rdma" in mount.nfs command, and document it in nfs(5).
+    Really, mountd should not be using stdio-style buffered file operations
+    on files in /proc to begin with.  A better solution would be to use
+    internally managed buffers and calls to write() instead of these stdio
+    calls, but that would be a more extensive change; so this is proposed
+    as a quick and not-so-dirty fix in the meantime.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Sean Finney <sean.finney@sonyericsson.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 44f09b7c4c79ca184a29138078c68a4db7aeb85a
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed Sep 8 13:26:34 2010 -0400
+commit 9274e94db85bac04e170414cb8e0f4be271cde90
+Author: Sean Finney <sean.finney@sonyericsson.com>
+Date:   Tue Apr 19 11:05:47 2011 -0400
 
-    mount.nfs: Use nfs_nfs_protocol() for checking for proto=rdma
+    mountd: Use a dynamic buffer for storing lists of gid's
     
-    Clean up: Now that nfs_get_proto() can recognize "rdma" we can re-use
-    nfs_nfs_protocol() instead of ad hoc checks for "proto=rdma".
+    Previously, in auth_unix_gid, group lists were stored in an array of
+    hard-coded length 100, and in the situation that the group lists for a
+    particular call were too large, the array was swapped with a dynamically
+    allocated/freed buffer.  For environments where users are commonly in
+    a large number of groups, this isn't an ideal approach.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit a77ca5c6a79486dc8c5a4c327fe5310f5d497766
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed Sep 8 13:25:56 2010 -0400
-
-    getport: Recognize "rdma" and "rdma6" netid
+    Instead, use malloc/realloc to grow the list on an as-needed basis.
     
-    The mount.nfs command must recognize the values of "rdma" and "rdma6"
-    with the "proto=" mount option.  Typically the mount.nfs command
-    relies on libtirpc or getprotobyname(3) to recognize netids and
-    translate them to protocol numbers.
-    
-    RFCs 5665 and 5666 define the "rdma" and "rdma6" netids.  IANA defines
-    a specific port number for NFS over RDMA (20049), but has not provided
-    a protocol name and number for RDMA transports, and is not expected
-    to.  The best we can do is translate these by hand, as needed, to get
-    RDMA mount requests to the kernel without erroring out.
-    
-    Only the forward translation is needed until such time that "rdma" and
-    "rdma6" start to appear in rpcbind registries.  For now, the version
-    and transport negotiation logic is skipped, avoiding rpcbind queries
-    for RDMA mounts.
-    
-    Note: As of kernel 2.6.36, the kernel's NFS over RDMA transport
-    capability does not support IPv6.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Sean Finney <sean.finney@sonyericsson.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 57f36cd692c56b3b62705b5fafef4c25561a39ff
-Author: Guillaume Rousse <Guillaume.Rousse@inria.fr>
-Date:   Thu Sep 9 10:33:47 2010 -0400
+commit a99269230a0e77e7bed4fa31c9547f0d61c7f206
+Author: Karel Zak <kzak@redhat.com>
+Date:   Wed Apr 6 12:39:21 2011 -0400
 
-    Clarification about options supported by different versions
+    mount: add --enable-libmount-mount
     
-    Signed-off-by: Guillaume Rousse <Guillaume.Rousse@inria.fr>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit b7df3370555877598d9f2ef49fae2ad4458e9f72
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Sep 9 10:27:17 2010 -0400
-
-    libexport.a: Refactor init_netmask()
+    This patch allows to link mount.nfs with libmount from util-linux >=
+    v2.19. The new libmount based code is enabled by CONFIG_LIBMOUNT and
+    is stored in mount_libmount.c. The old code is not affected by this
+    change.
     
-    Instead of a single function that can handle both AF_INET and AF_INET6
-    addresses, two separate functions might be cleaner.
+    The libmount does not have officially stable API yet, so the
+    --enable-libmount-mount is marked as experimental in the configure
+    help output.
     
-    The original plan was to keep code redundancy at a minimum, but the
-    resulting code was cumbersome at best.  I think I've traded a little
-    extra code for something that will be much easier to read, understand,
-    and maintain.
+    The ./configure option is the same as we use in util-linux to enable
+    support for libmount in mount(8).
     
-    I've also eliminated the "#if / #endif" instances inside the functions.
+    The addr= (and some other options necessary for remount/umount) are
+    stored to /etc/mtab or to /dev/.mount/utab. The utab file is *private*
+    libmount file. It's possible that some mount options (for example
+    user=) will be moved to kernel, so the utab will not be necessary.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 60abb9889cea52022adf9c8bb946e9d19d79f9ed
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 31 15:31:57 2010 -0400
-
-    libexport.a: IPv6 support in client_check()
+    About libmount:
     
-    Introduce support for IPv6 in client_check()'s helpers.  The local
-    addrs_match() twins are no longer needed since we can use
-    nfs_compare_addrs() now.
+      * supports systems without and with regular /etc/mtab
+      * does not store VFS and FS mount options in userspace
+      * manages user= option and evaluate permissions
+      * parses VFS mount options and generate MS_* flags
+      * parses /etc/{fstab,mtab}, /proc/mounts or /proc/self/mountinfo
+      * long-term goal is to use the same code in all mount.<type> helpers
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 965b15b855c0c621462256b0ab687fc32644255a
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 31 15:30:14 2010 -0400
-
-    libexport.a: IPv6 support for client_init_subnet()
+    Note, use
     
-    To parse and store an IPv6 host or subnet address, init_netmask()
-    needs to handle 128 bit subnet masks.
+       LIBMOUNT_DEBUG=0xffff mount.nfs foo:/path /path
     
-    Unfortunately what once was a pretty simple little function has grown
-    much larger.  This logic must now not only parse IPv6 addresses
-    correctly, but must also distinguish between IPv4 and IPv6.
+    to debug the library.
     
-    To avoid code duplication, I'm "bending" the cardinal rule of not
-    using "#ifdef" inside functions.
+    On systems with util-linux v2.19 the findmnt(8) command uses libmount
+    to list all/selected mount points:
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 2824097496f6b154befbf3b3d15dacf237b07f83
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 31 15:29:02 2010 -0400
-
-    libexport.a: Prepare init_subnetwork() for IPv6 support
-    
-    Retire the slash32 logic in inet_netmask() in favor of a more generic
-    netmask parser that can support IPv6 addresses.
+       $ findmnt /path
+       $ findmnt --mtab /path
     
-    If an invalid IP address string is given to inet_addr(3), it returns
-    INADDR_NONE, which is actually a "valid" address (255.255.255.255).
-    We're none the wiser to the substitution until something breaks later.
+    the --mtab appends userspace mount options (e.g. user=) to the output.
     
-    This patch provides better sanity checking of the parsed address, now
-    that such an error can be reported to client_init()'s callers.
-    We can also check the prefixlen value a little more carefully as well.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    CC: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Karel Zak <kzak@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 03fc34b23c2bff48f54c2d889d7851a31fb64a3d
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 31 15:27:19 2010 -0400
+commit c01e5ca6179b8f5b041605d9bbd75a0f76812d54
+Author: Karel Zak <kzak@redhat.com>
+Date:   Wed Apr 6 11:36:40 2011 -0400
 
-    libexport.a: Use host helper to parse address in client_init()
+    mount: move generic functions to utils.c and network.c
     
-    Take the first step towards making it possible to parse either IPv4 or
-    IPv6 addresses in client_init().  It won't handle IPv6 until
-    host_pton() has IPv6 support enabled, and it still doesn't deal with
-    IPv6 netmasks yet.
+    Move generic code that could be shared between standard mount.nfs and
+    libmount version to utils.c and network.c.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    CC: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Karel Zak <kzak@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 502edf1df5e727cf88b19b634f60392652f35ddc
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 31 15:25:35 2010 -0400
+commit d6c1b35c6b40243bfd6fba2591c9f8f2653078c0
+Author: Kevin Coffman <kwc@citi.umich.edu>
+Date:   Wed Apr 6 11:25:03 2011 -0400
 
-    libexport.a: Prepare to recognize IPv6 addresses in        client_gettype()
+    nfs-utils: Add support to svcgssd to limit the negotiated enctypes
     
-    The current open-coded parsing logic in client_gettype() will be hard
-    to modify to recognize IPv6 addresses.  Use a more generic mechanism
-    for detecting IP presentation addresses.
+    Recent versions of Kerberos libraries negotiate and use
+    an "acceptor subkey".  This negotiation does not consider
+    that a service may have limited the encryption keys in its
+    keytab.  A patch (http://src.mit.edu/fisheye/changelog/krb5/?cs=24603)
+    has been added to the MIT Kerberos code to allow an application
+    to indicate that it wants to limit the encryption types negotiated.
+    (This functionality has been available on the client/initiator
+    side for a while.  The new patch adds this support to the
+    server/acceptor side.)
     
-    IPv6 will be enabled automatically in client_gettype() when host_pton()
-    is changed to support IPv6 addresses.
+    This patch adds support to read a recently added nfsd
+    proc file to determine the encryption types supported by
+    the kernel and calls the function to limit encryption
+    types negotiated for the acceptor subkey.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 26fd34002585e6a5aa09204b0b01d836fa83dcf3
+commit 73840ef610accf4cf667427bc64805377c0d8394
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 24 07:19:34 2010 -0400
+Date:   Wed Apr 6 10:53:57 2011 -0400
 
-    exportfs: Use xlog() for error reporting
-    
-    exportfs already invokes xlog_open() because libexport.a uses xlog()
-    exclusively for error reporting and debugging messages.  If we can
-    use xlog() throughout exportfs itself, that enables xlog debugging
-    messages everywhere in the code path.
+    exports: add a configurable time-to-live for the kernel    cache entries
     
-    In addition, use xlog() instead of fprintf(stderr) for reporting
-    errors in exportfs.c, to be consistent with libexport.a and other
-    components of nfs-utils.
+    From: Trond Myklebust <Trond.Myklebust@netapp.com>
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 6d7babe6afae068e8a1054f785785d374788f5ee
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 24 07:18:04 2010 -0400
-
-    exportfs: exportfs.c no longer needs #include "xmalloc.h"
+    The fedfs ldap server will specify a ttl for its entries.
     
-    Clean up:  No calls to xmalloc() or xstrdup() here.  No need for the
-    double #include of xmalloc.h.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit e22f5a9c8e53a2373e8a939771e964ad315cdc5f
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 24 07:16:10 2010 -0400
-
-    statd: statd fails to monitor if no reverse mapping of mon_name exists
+    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
     
-    Commit 8ce130c4 switched in the new statd_canonical_name() function
-    that constructs a "unique" name statd can use to uniquely identify a
-    monitor record.
+    This is a refactoring change only.  There should be no change in
+    behavior.
     
-    The legacy statd would monitor a client that sent an IP address with
-    no reverse map as its caller_name.  To remain bug-for-bug compatible,
-    allow this case in the new statd.
+    Original patch had updates to utils/mountd/junctions.c, which no
+    longer exists.  These are not included here.
     
-    This shouldn't be a problem: statd_canonical_name() needs to create
-    a unique name for the monitored host so it can keep track of monitor
-    requests from the same remote.  The IP address itself should work as
-    well as the host's canonical name, in case there is no reverse
-    mapping.
+    Create a macro for the default cache TTL, which is used in several
+    places besides the export cache.
     
-    We still enforce the requirement that a mon_name that is a DNS name
-    must have a forward map to an IP address.
+    Make e_ttl unsigned.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 1bb84a09ff58d1314826945db2f3f1f63015e263
+commit 38e4c685410885a6d464ddd44eff4fd5e7f8459f
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 24 07:13:54 2010 -0400
+Date:   Wed Apr 6 10:49:52 2011 -0400
 
-    libexport: Fix IP address check in check_netgroup()
+    statd: Remove vestigial "-w" option from man page synopsis
     
-    Neil Brown reports that recent changes to replace
-    gethostby{addr,name}(3) with get{addr,info}name(3) may have
-    inadvertently broken netgroup support.
+    The synopsis of rpc.statd in its man page lists "-w" as a valid
+    option.  There is currently no support in the source code for a "-w"
+    option.
     
-    There used to be a gethostbyaddr(3) call in the third paragraph in
-    check_netgroup().  The reason for that gethostbyaddr(3) call was that
-    the first innetgr(3) call has already confirmed that hname is not a
-    member of the netgroup.  We also need to confirm that, if hname
-    happens to be an IP address, the hostname bound to that IP address is
-    not a member of the netgroup, either.
+    BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=199
     
-    Fix this by restoring appropriate address to hostname mapping of hname
-    before retrying the innetgr(3) call.
-    
-    See http://marc.info/?l=linux-nfs&m=128084830214653&w=2 .
-    
-    Introduced by commit 0509d3428f523776ddd9d6e9fa318587d3ec7d84.
-    
-    Reviewed-by: Neil Brown <neilb@suse.de>
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit abdc32b6af6f38a741a481aeefb5623916152498
+commit b57cd77c13831051ad974ae027d96cd88a8d0c59
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Aug 24 07:06:14 2010 -0400
+Date:   Wed Apr 6 10:48:38 2011 -0400
 
-    bexport: Add a common exit label to check_netgroup()
+    mount.nfs: Don't leak socket in nfs_ca_sockname()
     
-    check_netgroup() is going to be changed to free dynamically
-    allocated resources before it returns, so a common
-    exit point is needed.
+    Ensure the test socket is always closed before nfs_ca_sockname()
+    returns.  Otherwise it's orphaned.
     
-    Reviewed-by: Neil Brown <neilb@suse.de>
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 396aac50f5addea2f4d62c25600ca68788a56d97
-Author: Guillaume Rousse <Guillaume.Rousse@inria.fr>
-Date:   Tue Aug 17 17:47:38 2010 -0400
-
-    Fix the description of nfsversion mount option in the man nfs page
+    BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=197
     
+    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit e2003650c68cf47806fb24f7d88fae5524b70aab
+commit 502eef09d8050ffb87d394397c2780e1ef042d68
 Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 12:12:52 2010 -0400
+Date:   Wed Apr 6 10:46:06 2011 -0400
 
-    Remove warnings from nfsctl.c
+    Removed a warning from v4root.c
     
-    nfsctl.c: In function 'expsetup':
-    nfsctl.c:112: warning: signed and unsigned type in conditional expression
+    v4root.c:176:9: warning: variable 'ret' set but not used
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 1e472b3476cc6d7b95573b7d630d0fc51bebadf3
-Author: Steve Dickson <steved@redhat.com>
-Date:   Wed Aug 4 10:48:17 2010 -0400
-
-    Removed warnings from mountd.c
-    
-    mountd.c: In function 'mount_null_1_svc':
-    mountd.c:195: warning: unused parameter 'rqstp'
-    mountd.c:195: warning: unused parameter 'argp'
-    mountd.c:195: warning: unused parameter 'resp'
-    mountd.c: In function 'mount_dump_1_svc':
-    mountd.c:213: warning: unused parameter 'argp'
-    mountd.c: In function 'mount_umnt_1_svc':
-    mountd.c:224: warning: unused parameter 'resp'
-    mountd.c: In function 'mount_umntall_1_svc':
-    mountd.c:248: warning: unused parameter 'argp'
-    mountd.c:248: warning: unused parameter 'resp'
-    mountd.c: In function 'mount_export_1_svc':
-    mountd.c:258: warning: unused parameter 'argp'
-    mountd.c: In function 'mount_exportall_1_svc':
-    mountd.c:269: warning: unused parameter 'argp'
-    mountd.c: In function 'mount_dump_1_svc':
-    mountd.c:216: warning: unused parameter 'argp'
-    mountd.c: In function 'mount_umnt_1_svc':
-    mountd.c:227: warning: unused parameter 'resp'
-    mountd.c: In function 'mount_umntall_1_svc':
-    mountd.c:251: warning: unused parameter 'argp'
-    mountd.c:251: warning: unused parameter 'resp'
-    mountd.c: In function 'mount_export_1_svc':
-    mountd.c:261: warning: unused parameter 'argp'
-    mountd.c: In function 'mount_exportall_1_svc':
-    mountd.c:272: warning: unused parameter 'argp'
-    
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 14e6ec262e58e962c2d7e9161ca9c56529de3170
-Author: Steve Dickson <steved@redhat.com>
-Date:   Wed Aug 4 10:41:18 2010 -0400
-
-    Removed warnings from idmapd.c
-    
-    idmapd.c:120: warning: missing initializer
-    idmapd.c:120: warning: (near initialization for 'nfsd_ic[0].ic_event')
-    idmapd.c:121: warning: missing initializer
-    idmapd.c:121: warning: (near initialization for 'nfsd_ic[1].ic_event')
-    idmapd.c: In function 'flush_nfsd_cache':
-    idmapd.c:173: warning: comparison between signed and unsigned integer expressions
-    idmapd.c: In function 'dirscancb':
-    idmapd.c:384: warning: unused parameter 'fd'
-    idmapd.c:384: warning: unused parameter 'which'
-    idmapd.c: In function 'svrreopen':
-    idmapd.c:468: warning: unused parameter 'fd'
-    idmapd.c:468: warning: unused parameter 'which'
-    idmapd.c:468: warning: unused parameter 'data'
-    idmapd.c: In function 'clntscancb':
-    idmapd.c:474: warning: unused parameter 'fd'
-    idmapd.c:474: warning: unused parameter 'which'
-    idmapd.c: In function 'nfsdcb':
-    idmapd.c:488: warning: unused parameter 'fd'
-    idmapd.c: In function 'nfscb':
-    idmapd.c:663: warning: unused parameter 'fd'
-    idmapd.c: In function 'validateascii':
-    idmapd.c:850: warning: comparison between signed and unsigned integer expressions
-    idmapd.c:858: warning: comparison between signed and unsigned integer expressions
-    idmapd.c: In function 'getfield':
-    idmapd.c:916: warning: comparison between signed and unsigned integer expressions
-    
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 2ccfd2d5f390bcac7a44f8887cd3f15df1966e0f
+commit c2fa189a0467c25666f014cf9ff2576a9f54d682
 Author: Steve Dickson <steved@redhat.com>
-Date:   Wed Aug 4 10:29:28 2010 -0400
+Date:   Wed Apr 6 10:39:10 2011 -0400
 
-    Removed warnings from configfile.c
+    Removed a warning from exportfs.c
     
-    configfile.c:195: warning: 'inline' is not at beginning of declaration
-    configfile.c:232: warning: 'inline' is not at beginning of declaration
+    exportfs.c:280:29: warning: 'exp' may be used uninitialized in this function
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit bc8fdd5ebcabe57cacd382673ca9e4a79ff7b18e
+commit b98ae9df8c4904289c9390288325058b24caa423
 Author: Steve Dickson <steved@redhat.com>
-Date:   Wed Aug 4 10:26:13 2010 -0400
+Date:   Wed Apr 6 10:36:30 2011 -0400
 
-    Removed warnings from svcgssd_proc.c
+    Removed a warning from conffile.c
     
-    svcgssd_proc.c: In function 'send_response':
-    svcgssd_proc.c:135: warning: unused parameter 'f'
-    svcgssd_proc.c: In function 'handle_nullreq':
-    svcgssd_proc.c:434: warning: comparison of unsigned expression < 0 is always false
+    conffile.c:258:19: warning: 'j' may be used uninitialized in this function
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit be5b2ed57b0e0a3da91f4ec785718302d0351199
-Author: Steve Dickson <steved@redhat.com>
-Date:   Wed Aug 4 10:22:13 2010 -0400
+commit 012e1a4bf2a002e8cd4d5be3478bfa20a91cbfed
+Author: Masatake YAMATO <yamato@redhat.com>
+Date:   Mon Mar 7 08:36:19 2011 -0500
 
-    Removed warnings from network.c
+    Update man pages for /etc/exports.d
     
-    network.c: In function 'nfs_verify_family':
-    network.c:1366: warning: unused parameter 'family'
+    Man page updates for /etc/exports.d.
     
+    Signed-off-by: Masatake YAMATO <yamato@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 6b8d7c05fe738a4c7295754b4be552c703024f58
-Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 18:43:46 2010 -0400
+commit c7427b57e2be8ef0d57ad0618d4590c062b130f5
+Author: Masatake YAMATO <yamato@redhat.com>
+Date:   Mon Mar 7 08:18:51 2011 -0500
 
-    Removed warnings from nfs4mount.c
+    Read /etc/exports.d/*.export as extra export files
     
-    nfs4mount.c: In function 'fill_ipv4_sockaddr':
-    nfs4mount.c:149: warning: comparison between signed and unsigned integer expressions
+    This patch adding a capability to read /etc/exports.d/*.exports as
+    extra export files to exportfs.
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit cf2fd4869fdb77741bca9e3f713af49b889661b3
-Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 18:40:31 2010 -0400
-
-    Removed warnings from nfsmount.c
+    If one wants to add or remove an export entry in a script, currently
+    one may have to use sed or something tool for adding or removing the
+    line for the entry in /etc/exports file.
     
-    nfsmount.c: In function 'nfsmount':
-    nfsmount.c:513: warning: missing initializer
-    nfsmount.c:513: warning: (near initialization for 'mnt_server.saddr')
-    nfsmount.c:514: warning: missing initializer
-    nfsmount.c:514: warning: (near initialization for 'nfs_server.saddr')
+    With the patch, adding and removing an entry from a script is much
+    easier.
+    cat<<EOF... or mv can be used for adding. rm can be used for removing.
     
+    Signed-off-by: Masatake YAMATO <yamato@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 45a73911fff657942ec67317d000badb8e2c5282
+commit edb9b7f2ab9806afb9af31eabeb505fe454c51df
 Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 18:22:32 2010 -0400
+Date:   Sat Mar 5 16:17:01 2011 -0500
 
-    Removed warnings from svcgssd.c
+    Cleaned up a warning in rpcdispatch.c
     
-    svcgssd.c: In function 'sig_hup':
-    svcgssd.c:160: warning: unused parameter 'signal'
+    rpcdispatch.c:40:20: warning: comparison between signed and unsigned
+    integer expressions
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit b8ba21cedc6aac3b2847217caf55885bb1a74805
+commit 930323817b61877d61fb8ef57229013daa2e6091
 Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 18:13:45 2010 -0400
+Date:   Sat Mar 5 16:13:01 2011 -0500
 
-    Removed warnings from gssd_proc.c
+    mount: Remove MOUNT_CONFIG warnings
     
-    gssd_proc.c: In function 'create_auth_rpc_client':
-    gssd_proc.c:939: warning: comparison between signed and unsigned integer expressions
-    gssd_proc.c:939: warning: comparison between signed and unsigned integer expressions
-    gssd_proc.c: In function 'handle_krb5_upcall':
-    gssd_proc.c:1164: warning: comparison between signed and unsigned integer expressions
-    gssd_proc.c: In function 'handle_spkm3_upcall':
-    gssd_proc.c:1178: warning: comparison between signed and unsigned integer expressions
+    The following changes are needed to remove compile warnings when
+    MOUNT_CONFIG is not defined
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit f4321ac3466aa9d4c4e11ba232f1ff9bea561288
-Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 18:08:13 2010 -0400
+commit 3ef3dc8f1e87ba7a6eaa3c2a6965aff6c80ba414
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Thu Mar 3 17:26:33 2011 -0500
 
-    Removed warnings from krb5_util.c
+    mount: Recognize zero as a valid value for the port= option
     
-    krb5_util.c: In function 'realm_and_service_match':
-    krb5_util.c:617: warning: unused parameter 'context'
-    krb5_util.c: In function 'limit_krb5_enctypes':
-    krb5_util.c:1275: warning: unused parameter 'uid'
+    While zero is not a valid IP port number, zero does represent a valid
+    value for "port=".  It means "query rpcbind to discover the actual
+    non-zero port number to use".  So the parsing functions that handle
+    "port=" should not flag zero as an invalid value.
     
+    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit f89b109c04a8eab81bfa8b8fcdc7692673e13e49
-Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 17:53:47 2010 -0400
+commit b3a4dbfb61dad59829f5191d727267b2ea45937a
+Author: Mi Jinlong <mijinlong@cn.fujitsu.com>
+Date:   Wed Feb 9 11:29:42 2011 -0500
 
-    Removed warnings from gssd_main_loop.c
+    Gssd: modify wrong err message at handle_gssd_upcall
     
-    gssd_main_loop.c: In function 'dir_notify_handler':
-    gssd_main_loop.c:64: warning: unused parameter 'sig'
-    gssd_main_loop.c:64: warning: unused parameter 'si'
-    gssd_main_loop.c:64: warning: unused parameter 'data'
+    Modify wrong err message at handle_gssd_upcall when
+    sscanf encryption types fail.
     
+    Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit d2c329ba4b7ccdea76bcc857a73206eab68428f8
-Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 17:45:17 2010 -0400
+commit 45e4597bd570ed40221f51887cde7d7f096f55e7
+Author: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date:   Wed Feb 9 11:27:19 2011 -0500
 
-    Removed warnings from gssd.c
+    Support AD style kerberos automatically in rpc.gss
     
-    gssd.c: In function 'sig_hup':
-    gssd.c:78: warning: unused parameter 'signal'
+    An Active Directory KDC will only grant a TGT for UPNs, getting
+    a TGT for SPNs is not possible:
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 8a72ac3280ce8f9d0f48383d47dd06c80567bc09
-Author: Steve Dickson <steved@redhat.com>
-Date:   Tue Jul 20 17:19:20 2010 -0400
-
-    Removed warnings from atomicio.c
+    $ kinit -k host/ib5@ADS.ORCORP.CA
+    kinit: Client not found in Kerberos database while getting initial
+    credentials
     
-    atomicio.c: In function 'atomicio':
-    atomicio.c:48: warning: comparison between signed and unsigned integer expressions
+    The correct thing to do for machine credentials is to get a TGT
+    for the computer UPN <HOSTNAME>$@REALM:
+    $ kinit -k IB5\$
+    $ klist
+    12/22/10 11:43:47  12/22/10 21:43:47  krbtgt/ADS.ORCORP.CA@ADS.ORCORP.CA
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 14becdb7bc23f075f786325f7e953c2f928fe385
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 14:54:51 2010 -0400
-
-    Removed warnings from nfsstat.c
+    Samba automatically creates /etc/krb5.keytab entry for the computer UPN,
+    this patch makes gssd_refresh_krb5_machine_credential prefer it above
+    the SPNs if it is present.
     
-    nfsstat.c: In function 'print_callstats':
-    nfsstat.c:797: warning: comparison between signed and unsigned integer
-    expressions
-    nfsstat.c:801: warning: comparison between signed and unsigned integer
-    expressions
-    nfsstat.c:802: warning: comparison between signed and unsigned integer
-    expressions
-    nfsstat.c:805: warning: comparison between signed and unsigned integer
-    expressions
+    The net result is that nfs client works automatically out of the box
+    if samba has been used to setup kerberos via 'net ads join' 'net ads
+    keytab create'
     
-    nfsstat.c: In function 'print_callstats_list':
-    nfsstat.c:821: warning: comparison between signed and unsigned integer
-    expressions
-    nfsstat.c:828: warning: comparison between signed and unsigned integer
-    expressions
+    Tested using Windows Server 2003 R2 as the AD server.
     
-    nfsstat.c: In function 'unpause':
-    nfsstat.c:1111: warning: unused parameter 'sig'
+    Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit b594ee2b2a1b9c0c5823a7af279488f113f91be4
+commit 730f6986f86873513fa021a450eb55ccd0f2fbff
 Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 14:48:37 2010 -0400
+Date:   Wed Jan 26 07:49:19 2011 -0500
 
-    Removed warnings from nfssvc.c
+    Fixed segfault in rpc.mountd
     
-    nfssvc.c:184: warning: comparison between signed and unsigned integer expressions
-    nfssvc.c: In function 'nfssvc_setvers':
-    nfssvc.c:254: warning: comparison between signed and unsigned integer expressions
-    nfssvc.c: In function 'nfssvc_threads':
-    nfssvc.c:280: warning: comparison between signed and unsigned integer expressions
+    A unallocated piece of memory, instead of a NULL point, was being
+    used to initialize a ->next point in the mount link list which
+    caused a segfault after a few remote accesses via the showmount
+    command.
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 7b331fb9d24a71242a6c0a45a06c49174b552c64
+commit 544ed73d5ab27c1390833d5cf93b9585c151667d
 Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 14:43:26 2010 -0400
+Date:   Fri Jan 14 10:12:28 2011 -0500
 
-    Removed warnings from cache.c
+    Improve debugging in svcgssd
     
-    cache.c:812: warning: missing initializer
-    cache.c:812: warning: (near initialization for 'cachelist[0].f')
-    cache.c:813: warning: missing initializer
-    cache.c:813: warning: (near initialization for 'cachelist[1].f')
-    cache.c:814: warning: missing initializer
-    cache.c:814: warning: (near initialization for 'cachelist[2].f')
-    cache.c:815: warning: missing initializer
-    cache.c:815: warning: (near initialization for 'cachelist[3].f')
-    cache.c:816: warning: missing initializer
-    cache.c:816: warning: (near initialization for 'cachelist[4].f')
-    cache.c: In function 'cache_export_ent':
-    cache.c:887: warning: comparison between signed and unsigned integer expressions
-    cache.c:907: warning: comparison between signed and unsigned integer expressions
-    
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 9d5eaa2e939723c47649f0f112b43cc8ff414740
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 13:07:00 2010 -0400
-
-    Removed warnings from fsloc.c
+    Added in gss_display_error() which translates the GSS error into the
+    actual GSS macro name. Currently only the translation of these errors
+    are logged. Since those translations are buried deep in the kerberos
+    library code, having the actual GSS macro name makes it easier to
+    follow the code.
     
-    fsloc.c: In function 'replicas_lookup':
-    fsloc.c:149: warning: unused parameter 'key'
+    Moved the nfs4_init_name_mapping() call into main() so if debug is
+    enabled the DNS name and realms will be logged during start up.
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit e10000740fc4c323dbc8d501d7c0caeae12c19b5
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 12:39:52 2010 -0400
+commit 57be18b9ab08148a1cc9d5af588119885720be8b
+Author: Mi Jinlong <mijinlong@cn.fujitsu.com>
+Date:   Tue Jan 4 11:16:45 2011 -0500
 
-    Removed warnings from conffile.c
+    libnsm.a: modify return value to false from 0 at nsm_drop_privileges()
     
-    conffile.c: In function 'conf_parse_line':
-    conffile.c:301: warning: comparison between signed and unsigned integer expressions
-    
-    conffile.c: In function 'conf_load_defaults':
-    conffile.c:356: warning: unused parameter 'tr'
+    At nsm_drop_privileges(), for improving readability, unify
+    the return value.
     
+    Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 8810c9dd5b66a097a235e6eabd399739a44df63e
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 12:34:14 2010 -0400
+commit 5c498280fd9353ded3ea169841079bdae23418e2
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Mon Dec 13 14:50:45 2010 -0500
 
-    Remove warnings from nfs_mntent.c
+    libnsm.a: sm-notify sometimes ignores monitored hosts
     
-    nfs_mntent.c: In function 'mangle':
-    nfs_mntent.c:36: warning: comparison between signed and unsigned integer expressions
+    Monitored host information is stored in files under /var/lib/nfs.
+    When visiting entries in the monitored hosts directory, libnsm.a
+    examines the value of dirent.d_type to determine if an entry is a
+    regular file.
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 1ca569633e14c844e32d8e5e3a1c54be01a8b633
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 12:31:48 2010 -0400
-
-    emove warnings from cacheio.c
+    According to readdir(3), the d_type field is not supported by all
+    file system types.  My root file system happens to be one where d_type
+    isn't supported.  Typical installations that use an ext-derived root
+    file system are not exposed to this issue, but those who use xfs, for
+    instance, are.
     
-    cacheio.c: In function 'cache_flush':
-    cacheio.c:352: warning: comparison between signed and unsigned integer expressions
+    On such file systems, not only are remote peers not notified of
+    reboots, but the NSM state number is never incremented.  A statd warm
+    restart would not re-monitor any hosts that were monitored before
+    the restart.
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 0cdfd35cecc17eb1927f15d33205e43ec66675f2
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 12:28:09 2010 -0400
-
-    Remove warnings from svc_socket.c
-    
-    svc_socket.c: In function 'svcudp_socket':
-    svc_socket.c:160: warning: unused parameter 'reuse'
+    When writing support/nsm/file.c, I copied the use of d_type from the
+    original statd code, so this has likely been an issue for some time.
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 9c99b4633b185452614eb6c5630a30b30626a838
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 12:17:24 2010 -0400
-
-    Removed warnings from rpcdispatch.c
+    Replace the use of d_type in support/nsm/file.c with a call to
+    lstat(2).  It's extra code, but is guaranteed to work on all file
+    system types.
     
-    rpcdispatch.c: In function 'rpc_dispatch':
-    rpcdispatch.c:30: warning: comparison between signed and unsigned
-         integer expressions
-    rpcdispatch.c:35: warning: comparison between signed and unsigned
-         integer expressions
+    Note there is a usage of d_type in gssd.  I'll let gssd and rpcpipefs
+    experts decide whether that's worth changing.
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit b6e0ddd7bb3843bb8bb5ff56816b31bcf17adacd
-Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Jul 19 12:05:51 2010 -0400
-
-    Enable extra compile warnings (-Wextra) by default.
+    Fix for:
     
-    Added -Wextra to the CFLAGS which enables more checking
-    during compilation, which in turn, will hopefully flag
-    potential problems before they occur.
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=193
     
+    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 12af21aca517dfbaec465447d8336bcc4769f71d
-Author: Doug Nazar <nazard.michi@gmail.com>
-Date:   Mon Jul 19 11:08:46 2010 -0400
+commit 089df7c754d9ebab0a7b804f396626ac95fee2e6
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Mon Dec 13 14:47:42 2010 -0500
 
-    gssd: picking wrong creds
+    libnsm.a: Replace __attribute_noinline__
     
-    When not using machine credentials for root, if the machine
-    credential cache file is newer than the root credential file
-    the wrong file will get picked. Ignore the machine file in
-    this case.
+    Replace the __attribute_noinline__ form with
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit e2aa2c8c4cc21eb312a301855c2e211dedf93146
-Author: Doug Nazar <nazard.michi@gmail.com>
-Date:   Mon Jul 19 10:58:47 2010 -0400
-
-    mountd: Fix memcmp result comparison error for uuid match.
-    
-    Fixed Small typo in the new fs uuid comparison code
+      __attribute__((__noinline__)).
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit eafc5a8873b09482c71313f425080cce2031010a
-Author: Doug Nazar <nazard.michi@gmail.com>
-Date:   Mon Jul 19 10:48:34 2010 -0400
-
-    gssd: Fix endtime issue
+    Even though the compiler didn't complain about __attribute_malloc__,
+    also replace those in order to maintain consistent style throughout the
+    source file.
     
-    Commit 4c5ff6d4 removed the setting of endtime for a few contexts by
-    accident.
+    Fix for:
     
-    Now to figure out why I get stale handles on submounts.
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=194
     
+    Reported-by: "Gabor Z. Papp" <gzp@papp.hu>
+    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 0bd7e91cea26bcfc5581290e4cdd87870da29b9e
+commit 7869a76207d3f4b3bd4ab57b4a7a8807ac2ff0c6
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Jul 19 10:09:12 2010 -0400
+Date:   Mon Dec 13 14:36:15 2010 -0500
 
-    nfs-utils: Fix C aliasing rules violation in       nfs_getrpccaller()
+    sm-notify: Make use of AI_NUMERICSERV conditional
     
-    Squelch compiler warnings reported with -Wextra:
+    Gabor Papp reports nfs-utils-1.2.3 doesn't build on his system that
+    uses glibc-2.2.5:
     
-    In file included from statd.c:24:
-    ../../support/include/rpcmisc.h: In function nfs_getrpccaller_in:
-    ../../support/include/rpcmisc.h:58: warning: dereferencing type-punned
-    pointer might break strict-aliasing rules
-    ../../support/include/rpcmisc.h: In function nfs_getrpccaller:
-    ../../support/include/rpcmisc.h:63: warning: dereferencing type-punned
-    pointer might break strict-aliasing rules
+    make[3]: Entering directory
+    `/home/gzp/src/nfs-utils-1.2.3/utils/statd'
+    gcc -DHAVE_CONFIG_H -I. -I../../support/include   -D_GNU_SOURCE -Wall
+       -Wextra -Wstrict-prototypes  -pipe -g -O2 -MT sm-notify.o -MD
+       -MP -MF .deps/sm-notify.Tpo -c -o sm-notify.o sm-notify.c
+       sm-notify.c: In function 'smn_bind_address':
+    sm-notify.c:247: error: 'AI_NUMERICSERV' undeclared (first use in this
+    function)
+    sm-notify.c:247: error: (Each undeclared identifier is reported only
+    once
+    sm-notify.c:247: error: for each function it appears in.)
+    make[3]: *** [sm-notify.o] Error 1
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit a8715bec8bd671135f20fc0422d2a9fc0993758a
-Author: Kevin Constantine <kevin.constantine@disneyanimation.com>
-Date:   Tue Jun 22 17:43:19 2010 -0400
-
-    nfs-iostat.py: divide by zero with fresh mount
+    According to the getaddrinfo(3) man page, AI_NUMERICSERV is available
+    only since glibc 2.3.4.  getaddrinfo(3) seems to convert strings
+    containing a number to the right port value without the use of
+    AI_NUMERICSERV, so I think we can survive on older glibc's without it.
+    It will allow admins to specify service names as well as port numbers
+    on those versions.
     
-    When an export is freshly mounted, /proc/self/mountstats displays age = 0.
-    This causes nfs-iostat.py to divide by zero throwing an error.  When we
-    have age = 0, other stats are greater than 0, so we'll set age = 1 and
-    print the relevant stats.
+    There are uses of AI_NUMERICSERV in gssd and in nfs_svc_create().  The
+    one in nfs_svc_create() is behind HAVE_LIBTIRPC, and the other is a
+    issue only for those who want to deploy Kerberos -- likely in both
+    cases, a more modern glibc will be present.  I'm going to leave those
+    two.
     
-    Signed-off-by: Kevin Constantine <kevin.constantine@disneyanimation.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 9c3f7a220b4812c5d560db5fcacad790fc8b17af
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 13:31:38 2010 -0400
-
-    libexport.a: Remove unused hostent-based DNS helper        functions
-    
-    Clean up:  Get rid of hostent-based DNS helper functions in
-    libexport.a that have been replaced by addrinfo-based DNS helpers.
+    Fix for:
     
-    None of the original code remains, so replace the copyright notice as
-    well.
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=195
     
+    Reported-by: "Gabor Z. Papp" <gzp@papp.hu>
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 21015ace7d0a356b24a57540ccfeb41d941e78ed
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 13:06:40 2010 -0400
+commit e8dbaddc8465dcd07b53f8e80a537703dd0248ca
+Author: Sid Moore <learnmost@gmail.com>
+Date:   Fri Dec 3 09:19:06 2010 -0500
 
-    libexport.a: Replace matchhostname()
-    
-    So that exportfs can eventually support IPv6 addresses, copy statd's
-    getaddrinfo(3)-based matchhostname to exportfs, with adjustments for
-    dealing with export wildcards and netgroups.  Until exportfs has full
-    IPv6 support, however, we want to ensure that IPv6 addresses continue
-    to remain blocked in the address comparison code used by exportfs.  At
-    a later point we'll replace much of this with the generic functions
-    in sockaddr.h.
-    
-    Since it contains special logic for handling wildcard and netgroups,
-    this function is specialized for exportfs, and does not belong in
-    one of the shared libraries.
+    rpc.mountd: Checking RPC Procedure ID before process it
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 22d6566d473f71e241c791a02435d414648c99e8
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 12:51:42 2010 -0400
+commit 3c6973c595d62dc6452967d50ae8abe69f9f8bad
+Author: Mi Jinlong <mijinlong@cn.fujitsu.com>
+Date:   Mon Nov 29 10:59:10 2010 -0500
 
-    libexport.a: Add documenting comments
+    libnfs.a: fix a bug when parse section's arg
     
-    Clean up.  Add a few additional documenting comments for globally
-    visible functions.
+    When parsing section's arg at configure file, the pointer
+    should stop when fetch ']', and give the warning message.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 53928c0166dcc0acceaa995edb8551b48968b5dd
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 12:44:44 2010 -0400
+commit 86f7be64cafd17d4a3f164603484eaedb4757431
+Author: Harshula Jayasuriya <harshula@redhat.com>
+Date:   Mon Nov 22 11:22:31 2010 -0500
 
-    libexport.a: Make export_add() static
-    
-    Clean up: export_add() is not called from outside of export.c, so make
-    it a static helper.
+    nfs-utils: nfsstat: has_stats() does not function correctly for NFSv4 client stats
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 8940675a20967145b37a596334c25a54804435cc
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 12:43:55 2010 -0400
-
-    libexport.a: Make export_read() return void
+    The NFSv4 client procs/ops in "struct rpc_procinfo nfs4_procedures" is
+    used to generate the NFS client stats interface:
+    ------------------------------------------------------------
+    net 0 0 0 0
+    rpc 15 0 0
+    proc2 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+    proc3 22 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0
+    proc4 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+    0 0 0
+    0 0 0 0 0 0 0
+    ------------------------------------------------------------
+    Note, for proc4, the number 42. That is the number of stats that follow
+    on the same line. Currently nfsstat's has_stats() relies on this number
+    to be equal to CLTPROC4_SZ. Unfortunately this is not the case. I have
+    changed has_stats() not to rely on these two values being equal. This
+    should also allow nfsstat to work with different kernel versions that
+    expose a different number of NFS client ops.
     
-    Clean up: export_read()'s return value is always zero, and its only
-    caller never checks it.
+    * Fix has_stats()
+    * Stop print_clnt_list() printing server stats!
+    * Describe the option -3 and -4 completely in the nfsstat manpage.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Harshula Jayasuriya <harshula@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 0509d3428f523776ddd9d6e9fa318587d3ec7d84
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 12:43:01 2010 -0400
+commit 0868dcccb9a3bf3d022a32ff31311fe371484e77
+Author: Steve Dickson <steved@redhat.com>
+Date:   Sat Nov 20 15:01:21 2010 -0500
 
-    mountd: Replace "struct hostent" with "struct addrinfo"
-    
-    struct hostent can store either IPv4 or IPv6 addresses, but it can't
-    store both address families concurrently for the same host.  Neither
-    can hostent deal with parts of socket addresses that are outside of
-    the sin{,6}_addr field.
+    Enable nfsidmap to compile
     
-    Replace the use of "struct hostent" everywhere in libexport.a, mountd,
-    and exportfs with "struct addrinfo".  This is a large change, but
-    there are so many strong dependencies on struct hostent that this
-    can't easily be broken into smaller pieces.
+    Only enable the compilation of nfsidmap when libnfsidmap support it.
     
-    One benefit of this change is that hostent_dup() is no longer
-    required, since the results of getaddrinfo(3) are already dynamically
-    allocated.
-    
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 3ca5879be32c4c11750e12230ff588195fff0738
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 12:40:27 2010 -0400
+commit 6f07548141e710767d425e119d9823691293771d
+Author: Bryan Schumaker <bjschuma@netapp.com>
+Date:   Fri Nov 19 12:01:10 2010 -0500
 
-    exportfs: Add a common exit label in exportfs()
+    Add the new nfsidmap program
     
-    Clean up: Reduce code duplication by introducing a goto label for
-    freeing hp and exiting.  This will make replacing "struct hostent *"
-    with "struct addrinfo *" more straightforward in this code.
+    This patch adds the nfsidmap program to nfs-utils.  This program is
+    called by the nfs idmapper through request-keys to map between
+    uid / user name and gid / group name.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
+    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 94ce1eb94babb4c587b2826452fb053cba745098
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Tue Jun 22 10:41:03 2010 -0400
+commit 409487978593de13ae36be0ee56d8111ad6b3319
+Author: Steve Dickson <steved@redhat.com>
+Date:   Mon Nov 22 11:33:37 2010 -0500
 
-    libexport.a: Add helpers to manage DNS lookups
-    
-    Introduce DNS query helpers based on getaddrinfo(3) and
-    getnameinfo(3).  These will eventually replace the existing
-    hostent-based functions in support/export/hostname.c.
-    
-    Put some of these new helpers to immediate use, where convenient.
+    Removed a couple warnings from utils/mount/stropts.c
     
-    As they are part of libexport.a, I've added the forward declarations
-    for these new functions in exportfs.h rather than misc.h, where the
-    hostent-based forward declarations are currently.
+    stropts.c:740:6: warning: 'ret' may be used uninitialized in this function
+    stropts.c:653:6: warning: 'ret' may be used uninitialized in this function
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 8d61f2518bebe11c5fd0624857f83de1dceca991
-Author: NeilBrown <neilb@suse.de>
-Date:   Tue Jun 22 10:37:25 2010 -0400
+commit f4968a724c1d4162a8e2b9f6a19c460cc56c95f7
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Fri Oct 29 12:56:21 2010 -0400
 
-    Improve support for exporting btrfs subvolumes
+    nfs(5): Document remount behavior
     
-    If you export two subvolumes of a btrfs filesystem, they will both be
-    given the same uuid so lookups will be confused.
-    blkid cannot differentiate the two, so we must use the fsid from
-    statfs64 to identify the filesystem.
+    It appears that, for a long while, NFS "remount" mounts have
+    completely wiped the existing mount options in /etc/mtab for a given
+    mount point.  This is a problem for umount.nfs, since it reads its
+    options out of /etc/mtab to find out how to do the unmount.
     
-    We cannot tell if blkid or statfs is best without knowing internal
-    details of the filesystem in question, so we need to encode specific
-    knowledge of btrfs in mountd.  This is unfortunate.
+    The mount(8) command provides the NFS mount subcommand with the mount
+    options to perform the remount.  There are four cases to consider:
     
-    To ensure smooth handling of this and possible future changes in uuid
-    generation, we add infrastructure for multiple different uuids to be
-    recognised on old filehandles, but only the preferred on is used on
-    new filehandles.
+      1. Both the device and mount directory are specified on the
+         command line, and the target mount point is in /etc/fstab
     
-    Signed-off-by: NeilBrown <neilb@suse.de>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 9ac7a15017b876d4d8d3a4502ebaf954f36f7f54
-Author: Steve Dickson <steved@redhat.com>
-Date:   Thu Jun 3 08:53:22 2010 -0400
-
-    mount.nfs: silently fails when the network protocol is not found
+      2. Only one of the device and mount directory is specified on
+         the command line, and the target mount point is in
+         /etc/fstab
     
-    mount.nfs should display some type of error diagnostics when
-    the network protocol can not be determined.
+      3. Both the device and mount directory are specified on the
+         command line, and the target mount point is not in /etc/fstab
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 740171dea45a57e396a86fbda1579a465f101854
-Author: Steve Dickson <steved@redhat.com>
-Date:   Thu Jun 3 08:32:56 2010 -0400
-
-    mount: silently fails when bad option values are given
+      4. Only one of the device and mount directory is specified on
+         the command line, and the target mount point is not in
+         /etc/fstab
     
-    mount.nfs should not only fail when an invalid option values
-    are supplied (as it does), it should also print a diagnostic
-    message identifying the problem
+    Currently only case 4 works correctly.  In that case, mount(8)
+    provides the correct set of mount options to the mount.nfs
+    subcommand and it can update /etc/mtab correctly.
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 94c3d7c91de582cf29ff9100950ecd4a5fd1606b
-Author: Kevin Constantine <kevin.constantine@disneyanimation.com>
-Date:   Wed Jun 2 08:34:14 2010 -0400
-
-    nfsiostat.man: Add linebreak before --version option
+    Cases 1 and 3 replace all mount options in /etc/mtab with the options
+    provided on the command line during a remount.  Case 2 replaces the
+    mount options in /etc/mtab with a mix of options from /etc/fstab and
+    /etc/mtab.
     
-    The nfsiostat man file was missing a linebreak before the --verbose option
+    Cases 1 and 3 are historical behavior.  Basically this is a formal
+    interface to allow administrators to replace the mount options in
+    /etc/mtab completely, instead of merging in new ones.  The present
+    patch documents that behavior in nfs(5), and provides best practice
+    for remounting NFS mount points.
     
-    Signed-off-by: Kevin Constantine <kevin.constantine@disneyanimation.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 291b329ad1f5a65270097f4ec3a8dd465df42669
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon May 24 06:02:22 2010 -0400
-
-    mountd: Convert colons in IPv6 presentation addresses tosemicolons
+    There are near-term plans to address case 2 by fixing mount(8)
+    (provided by utils-linux-ng in most distributions).
     
-    The /var/lib/nfs/rmtab file delineates fields in each of its lines
-    with a ":".  The first field contains the IP address of a client, in
-    presentation format.  IPv6 presentation format addresses contain
-    colons, which screws up the field delineation of rmtab.
+    This is a partial fix for:
     
-    Use a simple simple scheme to convert the colons in incoming client
-    names to some other character, and then convert them back when the
-    rmtab file is read.
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=188
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 9e398e49be79af62fca8efb21849d8a2714dc92a
+commit 6d1a82b005994f759f2c847c0354413a24643da5
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon May 24 06:01:22 2010 -0400
+Date:   Thu Oct 28 13:15:22 2010 -0400
 
-    libexport.a: Refactor rmtab_read()
+    nfs(5): Grammar and style fixes
     
-    Clean up: Make it easier to add IPv6 support by refactoring part of
-    rmtab_read() into a helper function.
+    Clean up grammar and style issues introduced by recent updates.  Also,
+    I'm not certain inappropriate options are always ignored.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 2fd2dfd9ebb2de145d50039233bd2a53b7f03062
-Author: NeilBrown <neilb@suse.de>
-Date:   Mon May 24 05:55:26 2010 -0400
-
-    Mountd listens on 2 different versions for NFSv2 (MOUNTv1 and MOUNTv2)
-    and one for NFSv3 (MOUNTv3)
-    
-    When --no-nfs-version requests an NFS version to be disabled, the
-    code actually disabled the MOUNT version. This works is several cases,
-    but requires --no-nfs-version 1 to completely disable NFSv2, which
-    is wrong.
-    
-    So if we do disable 1, 2, and 3. mountd complain and won't run, it
-    is not possible to run just v4 - i.e. not listening for MOUNT requests
-    at all (as v4 doesn't need them).
-    
-    So change the handling of "--no-nfs-version 2" it disable MOUNTv1 as
-    well as
-    MOUNTv2, and allow mountd to continue running as long as one of
-    NFSv2 NFSv3 NFSv4 is enabled.
-    
-    Signed-off-by: NeilBrown <neilb@suse.de>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 6299a310d77e6495efdf7c50491f0b055fee2cfe
+commit ab2cdb859f738a25e2567a2ec674cfa78a0a175d
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed May 5 15:41:07 2010 -0400
+Date:   Thu Oct 28 13:13:19 2010 -0400
 
-    mountd/exportfs: Make m_addrlist field a nfs_sockaddr
-    
-    To store non-AF_INET addresses in the nfs_client structure, we need to
-    use more than in_addr for the m_addrlist field.  Make m_addrlist
-    larger, then add a few helper functions to handle type casting and
-    array indexing cleanly.
+    mount.nfs: mnt_freq and mnt_pass are always zero
     
-    We could treat the nfs_client address list as if all the addresses
-    in the list were the same family.  This might work for MCL_SUBNETWORK
-    type nfs_clients.  However, during the transition to IPv6, most hosts
-    will have at least one IPv4 and one IPv6 address.  For MCL_FQDN, I
-    think we need to have the ability to store addresses from both
-    families in one nfs_client.
-    
-    Additionally, IPv6 scope IDs are not part of struct sin6_addr.  To
-    support link-local IPv6 addresses and the like, a scope ID must be
-    stored.
+    Clean up.
     
-    Thus, each slot in the address list needs to be capable of storing an
-    entire socket address, and not simply the network address part.
+    No need to pass constant zeros to add_mtab() from its only call site.
+    Ensure that initialization of a struct mntent is consistent in both
+    places that it is done.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 6ff1fd42db18c657fbc5f81169a566b41d53e731
+commit bc4a0c42570d5620cc1bb32428e16b9c9b5f3863
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed May 5 14:42:01 2010 -0400
+Date:   Thu Oct 28 13:10:48 2010 -0400
 
-    libexport.a: Clean up client_add()
-    
-    Clean up: client_add()'s current callers never set unknown m_type
-    values, so the m_type check is unnecessary.
+    mount.nfs: Fix memory leak in nfs_sys_mount()
     
-    All of client_add()'s callers are in the same source file where it is
-    defined, so make it a static helper function.
+    This appears to have been left behind by last year's adjustments to
+    how the extra_opts string is constructed.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 9bb85c5e8d2285f82367c75df5530a71a9a5a5f2
+commit 1f237ac72e6f563908b350e11fd2bb866c003028
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed May 5 14:37:13 2010 -0400
+Date:   Thu Oct 28 13:09:38 2010 -0400
 
-    libexport.a: Refactor client_init()
+    mount: Fix compiler warning in nfs_parse_retry_option()
     
-    Clean up:  Move subnet hostname parsing logic out of client_init() to
-    make it simpler to introduce IPv6 support.
+    stropts.c: In function nfs_parse_retry_option:
+    stropts.c:131: warning: conversion to unsigned int from long int may
+    alter its value
     
-    Make client_init() a helper, since it's already static.
+    Make it more clear what the second argument is for, and flag the
+    switch fallthrough case.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 0a8bd742cc1412e2553f152ee0c3aab8c5570212
-Author: Mike Frysinger <vapier@gentoo.org>
-Date:   Fri Apr 23 12:22:53 2010 -0400
+commit 1ea2c3be33f2eb4630c5cdb78edf2bb670b294ab
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Thu Oct 28 12:12:12 2010 -0400
 
-    Make capabilities support optional
-    
-    The new code using libcap is quite minor, so rather than always reqiure
-    libcap support, make it a normal --enable type flag.  Current default
-    behavior is retained -- if libcap is found, it is enabled, else it is
-    disabled like every nfs-utils version in the past.
+    nfs-utils: Remove all uses of AI_ADDRCONFIG
     
-    Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit fbc038b7a5c7f5f102bf2c4fb149030d0092eec8
-Author: Mike Frysinger <vapier@gentoo.org>
-Date:   Fri Apr 23 12:18:27 2010 -0400
-
-    set +x on autogen.sh
+    It was reported that, if only "lo" is up,
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 08e1512e4a932f41867f0b515348b9402db50cbd
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Apr 23 12:09:35 2010 -0400
-
-    libexport.a: Allow malloc(3) failures in client_lookup() and friends
+      mount.nfs 127.0.0.1:/export /mount
     
-    Clean up: Use malloc(3) instead of xmalloc() in client_lookup() and
-    client_dup(), ensuring that a failed memory allocation here doesn't
-    cause our process to exit suddenly.
+    fails with "Name or service not known".
     
-    Allocation of nfs_client records and the m_hostname string are now
-    consistently handled with malloc(3), calloc(3), strdup(3), and
-    free(3).
+    "man 3 getaddrinfo" says this:
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit aa4b66b12b631885ed85f3ebe97e68b033407178
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Apr 23 12:08:49 2010 -0400
-
-    libexport.a: Allow m_hostname allocation to fail instead of exit
+      If hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4
+      addresses are returned in the list pointed to by res only if the
+      local system has at least one IPv4 address configured, and IPv6
+      addresses are only returned if the local system has at least
+      one IPv6 address configured.
     
-    Clean up: Replace xstrdup() with strdup(3) in client_init(), to
-    prevent the process from exiting if the memory allocation fails.
+    The man page oversimplifies here.  A review of glibc shows that
+    getaddrinfo(3) explicitly ignores loopback addresses when deciding
+    whether an IPv4 or IPv6 address is configured.
     
-    Note that both of client_init()'s callers set m_hostname equal to NULL
-    before calling, thus the extra free(3) at the top of client_init() is
-    unneeded.
+    This behavior around loopback is a problem not just for mount.nfs,
+    but also for RPC daemons that have to start up before a system's
+    networking is fully configured and started.  Given the history of
+    other problems with AI_ADDRCONFIG and the unpredictable behavior it
+    introduces, let's just remove it everywhere in nfs-utils.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 5d954d871fb265af584faef5df6e2e7e6ada7c3b
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Apr 23 12:02:34 2010 -0400
-
-    libexport.a: Allow client_init() to fail instead of exit
+    This fix addresses:
     
-    client_init()'s current callers can now deal correctly with a failure.
-    Get rid of code that can cause our process to exit in client_init(),
-    if address mask parsing or memory allocation fails.
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=191
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 75cbc8d3fc9e7c3750629bd72519770ab58b868f
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Apr 23 12:00:28 2010 -0400
+commit f8e315543b7f1db7f37a4bfe8ede3020cef62868
+Author: Jeff Layton <jlayton@redhat.com>
+Date:   Thu Oct 28 09:18:33 2010 -0400
 
-    libexport.a: Add client_free()
+    nfs-utils: fix default value for --enable-tirpc
     
-    Clean up: Introduce a helper to free a nfs_client record.
+    We need $enable_tirpc to be a tristate. 'yes' means that someone
+    explicitly requested building with tirpc. 'no' means that it was
+    explicitly disabled. Anything else means that no one specified a value.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 7fc6f6c6b68ba7fa1be6de05ce3b9e2d97b82ea4
-Author: Steve Dickson <steved@redhat.com>
-Date:   Fri Apr 16 10:56:29 2010 -0400
-
-    Add in autoconf support for mountstats and nfsiostats
+    Fix it by setting the value to a blank string so that the default is
+    properly undefined.
     
+    Reported-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: Jeff Layton <jlayton@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit d8ff9ef2828059bb2ee115d22f3c9579421daf54
+commit c62d756402509ca5d07c1fd4d2e5a9d78dc4171b
 Author: Steve Dickson <steved@redhat.com>
-Date:   Fri Apr 16 10:49:10 2010 -0400
+Date:   Tue Oct 19 15:54:35 2010 -0400
 
-    Introduce man page for the nfsiostats command
+    Updated rpc.mountd man page
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit c03fe46d62bc78cb52d400fa5a52dc4ce9947945
-Author: Steve Dickson <steved@redhat.com>
-Date:   Fri Apr 16 10:46:41 2010 -0400
-
-    Introduce man page for the mountstats command
+    Updated the rpc.mountd man page to no longer reference
+    v3 as the "newer" version and also mentioned v4 as
+    a supported version.
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit c4b2281c6c748b768de7a49af89660c9c1a68b11
+commit 79e9079e9af4e5c2aa1d77815df1147b26876eb8
 Author: Steve Dickson <steved@redhat.com>
-Date:   Fri Apr 16 13:31:57 2010 -0400
+Date:   Tue Oct 19 15:54:04 2010 -0400
 
-    Removed some miscellaneous warnings in the new gssd code.
+    Cleared up the sync option in exportfs man page
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 4c5ff6d48021731128c4fc13d51610645a6fcf5c
-Author: Kevin Coffman <kwc@citi.umich.edu>
-Date:   Mon Apr 12 17:13:25 2010 -0400
+commit 6f228ea26be06572de245aed5496aaa122cca5a8
+Author: Steve Dickson <steved@redhat.com>
+Date:   Fri Oct 15 17:20:28 2010 -0400
 
-    Add support for non-DES encryption types.
+    Removed duplicate entries in export man page
     
-    Sends a new format of context information to the kernel.
-    (Requires kernel support to do anything useful.)
+    The man page's paragraphs about "refer=" and "replicas="
+    each appear twice.
     
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 76be349d5dd07f55797cb9920cc275667258f10f
-Author: Kevin Coffman <kwc@citi.umich.edu>
-Date:   Thu Apr 15 08:32:20 2010 -0400
+commit 849b7072a04975bb5da09245fbcacb0cb754a909
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Thu Oct 14 10:33:25 2010 -0400
 
-    Try to use kernel function to determine supported Kerberos enctypes.
+    mountd: Clear mountd registrations at start up
     
-    This patch replaces a hard-coded list with a function to obtain
-    the Kerberos encryption types that the kernel's rpcsec_gss code
-    can support.  Defaults to old behavior if kernel does not supply
-    information.
+    Clear stale MNT registrations before mountd tries to create fresh
+    listeners, to ensure that mountd starts.  This is also what statd does.
     
+    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 48d13033dcb27eb3d9ea78c39692ff7c54095950
-Author: Kevin Coffman <kwc@citi.umich.edu>
-Date:   Mon Apr 12 17:06:30 2010 -0400
+commit 93dcf64cc4a9e67f693aea35c8193428015f4a30
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Wed Oct 13 13:57:52 2010 -0400
 
-    gssd: move function limit_krb5_enctypes into the exported functions area
+    behavior as file systems that use the monolithic /sbin/mount command.
+    See the MS_NOMTAB macro in utils-linux-ng/mount/mount.c.
     
-    cleanup: Move function limit_krb5_enctypes() from the section
-    containing static functions into the section containing
-    externally visible functions.
+    Note that mount(8) has MS_USERS and MS_USER in the "nomtab" category
+    as well, but mount.nfs needs to record those values so that unmounting
+    a user-mounted NFS file system can work.
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 470448e77bd673b206cf40820f966dcb8f029f27
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Apr 16 13:03:20 2010 -0400
-
-    libexport.a: export_find() should handle address parsing errors
+    While we're here, fix some white space damage in fix_opts_string().
     
-    An address mask parsing error can cause client_init(), and therefore
-    client_dup(), to make our process exit suddenly.  Soon we want to add
-    more complex address parsing in client_init(), so we need this
-    interface to be a little more robust.
+    This is a partial fix for:
     
-    Since export_find() can return NULL in some cases, it can handle NULL
-    returns from its subroutines if an address parsing error occurs, or if
-    memory is exhausted.  Allow for client_dup() to return NULL instead of
-    exiting sideways.
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=188
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 9b7cc679c70d00af3f44dc6a8b44a360a2423d64
+commit dc08c702a6c7f824f317af561f491635ee898a71
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Apr 16 13:02:15 2010 -0400
+Date:   Wed Oct 13 13:55:10 2010 -0400
 
-    libexport.a: Add export_free()
+    umount.nfs: Distinguish between nfs4 and nfs mounts
     
-    Clean up: Introduce a helper to free an nfs_export record.
+    Neil Brown reports that umount.nfs is still confused by "-t nfs -o
+    vers=4" mounts.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 30eff9c26141746fb26efb1af60d5cbe7a16ebae
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 15 08:59:18 2010 -0400
-
-    libexport.a: Add helper for populating m_addrlist[]
+    /etc/mtab can be confused.  /proc/mounts is authoritative on the
+    fstype of a mount.  Have umount.nfs consult it to determine which
+    mechanism to use for unmounting.  The code to read /proc/mounts was
+    lifted from the nfsstat command.
     
-    Clean up: Move common code that populates an nfs_client record's
-    m_addrlist to a helper function.  This eliminates a little code
-    duplication, and makes it simpler to add IPv6 support later.
+    The code introduced by this patch may look like belt-n-suspenders, but
+    we have two use cases to consider:
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit e1c93f691348392ee36b763bf57946540891ff16
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 15 08:57:29 2010 -0400
-
-    libexport.a: Reduce code duplication in client_init()
+      1.  Old kernels don't support the "vers=4" mount option, so
+          umount.nfs must look for the "nfs4" fstype
+      2.  Upcoming kernels may eliminate support the "nfs4" fstype, so
+          umount.nfs must look for the "vers=4" mount option
     
-    Clean up:  Most cases in client_init() set clp->m_naddr to zero.  Move
-    it to the common part of the function, and simplify the logic.  This
-    will make adding IPv6 support here more straightforward.
+    Thus this logic checks for "nfs4" first then looks for the NFS version
+    setting.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 1fc99e6d5d6b9401e380ee756a4251c86a3b8d54
-Author: Mike Frysinger <vapier@gentoo.org>
-Date:   Thu Apr 15 08:49:28 2010 -0400
-
-    set +x on t0001-statd-basic-mon-unmon.sh
+    Note that we could handle unmounting entirely in the kernel, but that
+    won't help older kernels that have this issue.
     
-    The test framework tries to exec this script, but it fails because it
-    lacks the +x bit.
+    See:
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=189
     
-    Signed-off-by: Mike Frysinger <vapier@gentoo.org>
+    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit bf867b09201abb155b52e81aeb08757b2f7c6937
+commit 17962b82afb68ca8e6b0d3f432d36c6c7c4980ea
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 8 11:01:14 2010 -0400
+Date:   Wed Oct 13 13:01:51 2010 -0400
 
-    libexport.a: replace xlog(L_FATAL) in client_check()
+    mount.nfs: mountproto does not support RDMA
     
-    Clean up: Prevent the process from exiting in client_check().  Report
-    bad m_type values, but return 0.
+    Clean up.  Our client does not support the MNT protocol on RDMA.
     
-    This removes another site where a mountd or exportfs process can exit
-    sideways.
+    nfs_mount_protocol() isn't invoked for RDMA mounts (they are shunted
+    off before nfs_options2pmap() is invoked).  But in case it ever is,
+    it should return the expected response.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit a39b43b81a8e7b70310f250c5ffd77816577cd6c
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 8 10:55:02 2010 -0400
+commit 73c61fa5cd114fa6eae0e095724ed63aa66a4a6b
+Author: NeilBrown <neilb@suse.de>
+Date:   Wed Oct 13 12:08:41 2010 -0400
 
-    libexport.a: Refactor wildcard checking in client_check()
+    gcc complained:
     
-    Clean up: refactor wildcard logic out of client_check() to make it
-    easier to introduce IPv6 support.
+    client.c: In function 'init_netmask6':
+    client.c:181:1: warning: no return statement in function returning
+    non-void
     
-    Match the style used for client_check_{fqdn,subnetwork,netgroup}.
+    and Suse' build system complained
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+    I: Program returns random data in a function
+    E: nfs-utils no-return-in-nonvoid-function client.c:181
+    
+    when I built without --enable-ipv6
+    
+    Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+    Signed-off-by: NeilBrown <neilb@suse.de>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 346ca35298e45e55a58d0f566c3b32b69102c6de
+commit 7e90281b88c05b01c61152b54a0cf2faec45b09c
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 8 10:54:01 2010 -0400
+Date:   Wed Oct 13 12:02:32 2010 -0400
 
-    libexport.a: Refactor netgroup checking in client_check()
+    mount.nfs: Eliminate compiler warnings in utils/mount/network.c
     
-    Clean up: refactor netgroup logic out of client_check() to make it
-    easier to introduce IPv6 support.
+    Clean up.
     
-     +  Use preferred style of keeping #ifdef out of the middle of
-        function definitions.  Squelch compiler warnings for "#ifndef
-        HAVE_INNETGR" by using __attribute__((unused)).
+    network.c: In function get_socket:
+    network.c:431: warning: dereferencing type-punned pointer might break
+        strict-aliasing rules
     
-     +  Use preferred style of not using curly braces around switch cases.
+    network.c: In function probe_bothports:
+    network.c:759: warning: dereferencing type-punned pointer might break
+        strict-aliasing rules
+    network.c:762: warning: dereferencing type-punned pointer might break
+        strict-aliasing rules
     
-     +  Match style used for check_{fqdn,subnetwork}.
+    network.c: In function nfs_probe_statd:
+    network.c:775: warning: dereferencing type-punned pointer might break
+        strict-aliasing rules
     
-     +  Clarify comment documenting use of h_aliases
+    network.c: In function nfs_call_umount:
+    network.c:904: warning: dereferencing type-punned pointer might break
+        strict-aliasing rules
+    
+    network.c: In function nfs_ca_sockname:
+    network.c:1106: warning: dereferencing type-punned pointer might break
+        strict-aliasing rules
+    network.c:1112: warning: dereferencing type-punned pointer might break
+        strict-aliasing rules
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 3455138100064d0213b124c72453accde2276be5
+commit 57385cf87790c0cbdfddfccdde66bd2c8da45923
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 8 10:52:33 2010 -0400
+Date:   Wed Oct 13 11:59:30 2010 -0400
 
-    libexport.a: Remove unused function client_checkaddr()
+    mount.nfs: Eliminate compiler warning in utils/mount/parse_opt.c
     
-    Clean up.
+    parse_opt.c: In function po_rightmost:
+    parse_opt.c:517: warning: conversion to int from unsigned int may
+        change the sign of the result
+    
+    "i" contains the function's result value, so it should be defined as
+    the same type as the function's return type.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit a4e3d5c53195c789ae26697a0b2ecdf05d76a85b
+commit 1ee10ef034cbca86da4df271ac4097a948e7ab59
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 8 10:51:54 2010 -0400
+Date:   Wed Oct 13 11:58:27 2010 -0400
 
-    libexport.a: Factor SUBNETWORK checking out of     check_client()
+    mount.nfs: Eliminate compiler warning in utils/mount/nfsumount.c
     
-    Clean up:  Factor the MCL_SUBNETWORK case out of check_client() and
-    client_checkaddr().  This will make it easier to add IPv6 support
-    eventually.
-    
-    The logic in the new helper function will get a little more tangled
-    once IPv6 support is introduced.  Each slot in the clp address list
-    eventually may contain an address from either address family.
+    Clean up.
     
-    Note that the switch statement in client_checkaddr() is redundant,
-    since clp->cl_mtype is loop invariant.  This change makes SUBNETWORK
-    client checking more computationally efficient, at the cost of a few
-    extra lines of code.
+    nfsumount.c:374: warning: ISO C forbids omitting the middle term of
+       a ?: expression
     
-    This commit should not change code behavior in any way.
+    This is also probably harmless, but let's make the code unambiguous.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 6abde64e6a605443dfc283ffb2642cb853f8b5b0
+commit e9c97e4f7075e563d7a442ca8298ac56bafba0d5
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Thu Apr 8 10:50:41 2010 -0400
+Date:   Wed Oct 13 11:56:58 2010 -0400
 
-    libexport.a: Factor FQDN checking out of check_client()
-    
-    Clean up:  Factor the MCL_FQDN case out of check_client() and
-    client_checkaddr().  This will make it easier to add IPv6 support
-    eventually.
+    mount.nfs: Eliminate compiler warning in utils/mount/nfsumount.c
     
-    The logic in the new helper function will get a little more tangled
-    once IPv6 support is introduced.  Each slot in the clp address list
-    eventually may contain an address from either address family.
+    Clean up.
     
-    Note that the switch statement in client_checkaddr() is redundant,
-    since clp->cl_mtype is loop invariant.  This change makes FQDN client
-    checking more computationally efficient, at the cost of a few extra
-    lines of code.
+    nfsumount.c:265: warning: no previous prototype for nfsumount
     
-    This commit should not change code behavior in any way.
+    It's also a good idea if the compiler can ensure that the prototype
+    in nfsmount.h matches the actual function defined in nfsumount.c.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit e8a54a3d5e32c9de009f84d1ef3f26d2dffbf226
-Author: Steve Dickson <steved@redhat.com>
-Date:   Thu Apr 8 10:43:49 2010 -0400
-
-    Remove some warnings that were introduced by commit 6ca440c
-    
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit 132744e9f8885254bcf213c90009d40adeb716bc
+commit e2b6d9cbaf20df26dd371a715fce3ae158f37126
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Mar 22 10:18:00 2010 -0400
+Date:   Wed Oct 13 11:54:49 2010 -0400
 
-    libexport.a: e_fslocdata should be freed with free(3)
+    mount.nfs: Eliminate compiler warnings in utils/mount/mount.c
     
-    Clean up: Since e_fslocdata is allocated with strdup(3), and not
-    xstrdup(), it should be freed with free(3), and not xfree().
+    Clean up.
     
-    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit e3b0046b4b12a6e05c0a7afd59ca5431ded51e96
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Mar 22 10:16:04 2010 -0400
-
-    libexport.a: Fix whitespace damage in      support/export/export.c
+    mount.c: In function parse_opt:
+    mount.c:354: warning: conversion to size_t from int may change the
+        sign of the result
+    mount.c:354: warning: conversion to int from size_t may change the
+        sign of the result
+    mount.c:359: warning: conversion to size_t from int may change the
+        sign of the result
+    mount.c:359: warning: conversion to int from size_t may change the
+        sign of the result
+    mount.c: In function parse_opts:
+    mount.c:374: warning: conversion to int from size_t may change the
+        sign of the result
+    mount.c:377: warning: conversion to size_t from int may change the
+        sign of the result
     
-    Clean up whitespace damage introduced by commit 4cacc965.
+    Character string lengths are usually size_t anyway.  We can easily
+    avoid the implicit type cast here.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 5f722d8855ebcb2d041e182c8c69c8cbee4bf408
+commit 013e8ec9ffb9f28f97e58299719023faf846a029
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Mar 22 10:13:15 2010 -0400
+Date:   Wed Oct 13 11:53:44 2010 -0400
 
-    libexport.a: Clean up client_compose() and client_member()
+    mount.nfs: Eliminate compiler warning in utils/mount/mount.c
+    
+    Clean up.
+    
+    mount.c: At top level:
+    mount.c:324: warning: no previous prototype for ?mount_usage?
     
-    Clean up:  Replace outdated comments, and fix some function
-    declarations.  Use proper type for a couple of automatic variables.
+    mount_usage() has no callers outside of utils/mount/mount.c and no
+    prototype is provided in a header file.  Make it static.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit aa4c771fc359e097a3a6c3637f78c7bed7c450e9
+commit 47480475c99335c1203e81662f815b62573c19e8
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Mon Mar 22 10:10:59 2010 -0400
+Date:   Wed Oct 13 11:50:57 2010 -0400
 
-    libexport.a: Remove dead code
+    mount.nfs: Eliminate compiler warnings in utils/mount/version.h
     
-    Clean up:  I can't find any call sites for client_find() or
-    client_match().
+    Clean up.
+    
+    In file included from mount.c:50:
+    version.h: In function linux_version_code:
+    version.h:48: warning: conversion to unsigned int from int may
+        change the sign of the result
+    version.h:48: warning: conversion to unsigned int from int may
+        change the sign of the result
+    version.h:48: warning: conversion to unsigned int from int may
+        change the sign of the result
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 0935cebc1e130c6adfd870c88a6493277c84d47f
+commit 00885013dccbe00f5cc4e19223cf18e85a8e616a
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Mar 19 16:14:26 2010 -0400
+Date:   Wed Oct 13 11:44:23 2010 -0400
 
-    mount: Mount should retry unreachable hosts
+    mount.nfs: Eliminate compiler warning in utils/mount/mount.c
     
-    Currently if a server is up but not responding (ie, it answers ARP
-    requests, but not NFS or RPC requests), mount retries or backgrounds
-    itself waiting for the server.
+    Clean up.
     
-    If the server is not responding on the network at all, mount fails
-    the mount request immediately.
+    In file included from mount.c:41:
+    mount_config.h:35: warning: no previous prototype for mount_config_opts
     
-    Users might find it more useful if mount retried in both cases.
+    Functions defined in include files are usually declared as "static
+    inline," eliminating the need for a forward declaration.
     
-    Note that this change means attempting to mount using a misspelled
-    server name will "hang" for the retry amount.  I suppose the error
-    message isn't very helpful whether it fails immediately or waits
-    a couple of minutes, though I imagine that an unreachable server is a
-    much more common occurrence than a misspelling.
+    While I was there, I also fixed the macro that prevents including
+    mount_config.h multiple times, and fixed some white space damage.
     
-    Reported-by: Daniel Goering <g_daniel@gmx.net>
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit baa41b2c78e796540c45692ea35214f7090a78cb
+commit ffa577350b03ddd421d455a8cd4cff86e3718264
 Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Fri Mar 19 16:03:45 2010 -0400
+Date:   Wed Oct 13 11:38:22 2010 -0400
 
-    sm-notify: Send fully-qualified and unqualified mon_names
-    
-    During any file locking interaction between an NFS client and server,
-    the client tells the server what hostname it will use as the mon_name
-    argument of the SM_NOTIFY request sent by the client when it reboots.
-    This is the "caller_name" argument of an NLMPROC_LOCK request.
-    
-    The server, however, never tells the client what mon_name argument
-    it will use when sending an SM_NOTIFY request.  In order to recognize
-    the server, clients usually guess what mon_name the server might
-    send, by using the server hostname provided by the user on the mount
-    command line.
+    mount.nfs: Eliminate compiler warnings
     
-    Frequently, the user provides an unqualified server name on the mount
-    command.  The server might then call the client back with a fully
-    qualified domain name, which might not match in some cases.
-    
-    Solaris, and perhaps other implementations, attempt to mitigate this
-    problem by sending two SM_NOTIFY requests to each peer: one with an
-    unqualified mon_name argument, and one with a fully qualified mon_name.
+    Clean up.
     
-    Implement such a scheme for sm-notify.
+    fstab.c: In function ?lock_mtab?:
+    fstab.c:385: warning: declaration of ?errsv? shadows a previous local
+    fstab.c:367: warning: shadowed declaration is here
+    fstab.c:407: warning: declaration of ?errsv? shadows a previous local
+    fstab.c:367: warning: shadowed declaration is here
+    fstab.c:417: warning: declaration of ?tries? shadows a previous local
+    fstab.c:325: warning: shadowed declaration is here
+    fstab.c:422: warning: declaration of ?errsv? shadows a previous local
+    fstab.c:367: warning: shadowed declaration is here
     
-    Since my_name is almost always the fully-qualified hostname associated
-    with the local system, just wiping the left-most '.' in the my_name
-    argument and sending another SM_NOTIFY is nearly always sufficient.
+    These are probably harmless.  Reusing a variable name, however, is a
+    little confusing to follow when reading the code.
     
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 900df0e7c0b9006d72d8459b30dc2cd69ce495a5
-Author: Chuck Lever <chuck.lever@oracle.com>
-Date:   Wed Mar 17 06:15:08 2010 -0400
+commit 5fe118b838254023d83424c5010ae73a91ec267d
+Author: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date:   Wed Oct 13 11:27:21 2010 -0400
 
-    sm-notify: Use my_name when sending SM_NOTIFY requests
+    export: Ensure that we free struct exportent->e_uuid
+    
+    Currently, the exportent->e_uuid is initialised in
+    support/nfs/exports.c:parseopts(), but it is never freed.
     
-    The mon_name argument of an SM_NOTIFY request is a string that
-    identifies the rebooting host.
+    Also ensure that exportent->e_uuid is duplicated correctly in
+    dupexportent().
     
-    sm-notify should send the my_name provided by the local lockd at the
-    time the remote was monitored, rather than cocking up a mon_name
-    argument based on the present return value of gethostname(3).  If the
-    local system's hostname happened to change after the last reboot, then
-    the string returned by gethostname(3) will not be recognized by the
-    remote.  Thus the remote will never initiate lock recovery for the
-    original named host, possibly leaving stale locks.
+    Adjusted to account for the new export_free() helper.
     
-    The existing behavior of using the -v command line option as the
-    mon_name argument is preserved, but we now prevent sending an IP
-    presentation address, as some non-Linux implementations don't
-    recognize addresses as valid mon_names.
+    Also, e_uuid points to memory that is always allocated with strdup(3),
+    not with xstrdup().  Thus it must be freed via free(3) and not via
+    xfree().
     
+    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
     Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-    Reviewed-by: Jeff Layton <jlayton@redhat.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 70c59e231e7257ac93b68ba4b844f8d10a6af4a8
-Author: J. Bruce Fields <bfields@citi.umich.edu>
-Date:   Mon Mar 8 15:02:26 2010 -0500
+commit 656028f9925f5817c5a37565d27159973db84ec3
+Author: Chuck Lever <chuck.lever@oracle.com>
+Date:   Wed Oct 13 11:22:07 2010 -0400
 
-    mountd: trivial: name parameters for clarity
+    libnfs.a: Allow multiple RPC listeners to share    listener port number
     
-    Part of the reason for the previous bug was confusion between "subpath"
-    and "path"; which is the shorter path, and which the longer?
+    Normally, when "-p" is not specified on the mountd command line, the
+    TI-RPC library chooses random port numbers for each listener.  If a
+    port number _is_ specified on the command line, all the listeners
+    will get the same port number, so SO_REUSEADDR needs to be set on
+    each socket.
     
-    "child" and "parent" seem less ambiguous.
+    Thus we can't let TI-RPC create the listener sockets for us in this
+    case; we must create them ourselves and then set SO_REUSEADDR (and
+    other socket options) by hand.
     
-    Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-    Signed-off-by: Steve Dickson <steved@redhat.com>
-
-commit a064fde8c2615333227de97d159bb338d4ac640d
-Author: J. Bruce Fields <bfields@citi.umich.edu>
-Date:   Mon Mar 8 14:59:01 2010 -0500
-
-    mountd: fix path comparison for v4 crossmnt
+    Different versions of the same RPC program have to share the same
+    listener and SVCXPRT, so we have to cache xprts we create, and re-use
+    them when additional requests for registration come from the
+    application.
     
-    This was obviously wrong, since path[strlen(path)] == '\0'
-    should always be true.
+    Though it doesn't look like it, this fix was "copied" from the legacy
+    rpc_init() function.  It's more complicated for TI-RPC, of course,
+    since a TI-RPC application can set up listeners with a nearly
+    arbitrary number of address families and socket types, not just the
+    two listeners that legacy RPC applications can set up (one for AF_INET
+    UDP and one for AF_INET TCP).
     
-    Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
+    See:
+      https://bugzilla.linux-nfs.org/show_bug.cgi?id=190
+    
+    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 6ca440c2661dccb05ae74ffb65817e9c30f05c8a
+commit 1296be71ebae4c0d7da61cc1077d97562d3bc549
 Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Mar 8 11:22:46 2010 -0500
+Date:   Wed Oct 13 10:17:58 2010 -0400
 
-    mountd: fix --manage-gids hang due to int/uint bug
-    
-    A uid or gid should be represented as unsigned, not signed.
+    nfs-utils: Fixed typo in NFS man page
     
-    The conversion to signed here could cause a hang on access by an unknown
-    user to a server running mountd with --manage-gids; such a user is
-    likely to be mapped to 232-1, which may be converted to 231-1 when
-    represented as an int, resulting in a downcall for uid 231-1, hence the
-    original rpc hanging forever waiting for a cache downcall for 232-1.
+    Chuck pointed out there was a grammar typo in addition to the spelling
+    typo.  Here is a revised version of the patch.
     
-    Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
+    Signed-off-by: Jim Rees <rees@umich.edu>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 84346b7d7e69c113d6dbf03f2646a47b0e74a6b8
+commit 9afbdbad4436df6f7a5a501c6e4db04c3a5bbb08
 Author: Steve Dickson <steved@redhat.com>
-Date:   Mon Mar 8 10:24:44 2010 -0500
+Date:   Wed Oct 13 10:15:12 2010 -0400
 
-    Use authunix_create() instead of authsys_create() to fix regression.
+    Fix style nits in atomicio.c
     
-    Commit 409b8 introduced a regression when the --disable-tirpc
-    configuration flag is set. The authsys_create() interface, which
-    was introduced, does not exist in the legacy glibc library.
-    
-    Since the authsys_create() interface is a redefined of the
-    authunix_create() interface, which is defined in glibc, using
-    authunix_create() resolves the regression,
-    
-    Acked-by: Jeff Layton <jlayton@redhat.com>
+    Signed-off-by: Jim Rees <rees@umich.edu>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 409b89cc7106154780400c6b2bdce46bc9d5db4b
-Author: Jeff Layton <jlayton@redhat.com>
-Date:   Mon Mar 1 08:07:34 2010 -0500
+commit c117b7a1f29db65d139824ba5bab2a58bf5609e2
+Author: Steve Dickson <steved@redhat.com>
+Date:   Wed Oct 13 10:09:53 2010 -0400
 
-    nfs-utils: add and use nfs_authsys_create
-    
-    The current mount, umount and showmount code uses
-    authunix_create_default to get an auth handle. The one provided by glibc
-    returned a truncated list of groups when there were more than 16 groups.
-    libtirpc however currently does an abort() in this case, which causes
-    the program to crash and dump core.
+    nfs-utils: Move common code into support
     
-    nfs-utils just uses these auth handles for the MNT protocol, so the
-    group list doesn't make a lot of difference here. Add a new function
-    that creates an auth handle with a supplemental gids list that consists
-    only of the primary gid. Have nfs-utils use that function anywhere that
-    it currently uses authunix_create_default. Also, have the caller
-    properly check for a NULL return from that function.
+    There are several source files and headers present in the ./utils/idmapd
+    directory which are also usable in a doimapd daemon. Because of this we
+    move that support into the support directory such that it can be shared by
+    both daemons.
     
-    Signed-off-by: Jeff Layton <jlayton@redhat.com>
+    Signed-off-by: Jim Rees <rees@umich.edu>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 9c8c2cd50d3cf0316c2a1bdf6cb9efc7e1a20be9
-Author: Trond Myklebust <Trond.Myklebust@netapp.com>
-Date:   Mon Mar 1 07:37:49 2010 -0500
+commit 8c217b9623c8304608196aeb2f7360abfdf987c8
+Author: Suresh Jayaraman <sjayaraman@suse.de>
+Date:   Wed Sep 29 07:14:14 2010 -0400
 
-    Fix a typo in commit 6d5ac3fa (nfsd: Disble NFS 4.1 functionality by
-    default).
-    
-    We did not really intend to make NFSv4.0 support conditional on NFSv4.1
-    being enabled.
+    The kernel 2.6.37 has a add new mount option: local_lock.
+    Document the new option in the nfs(5) man page.
     
+    Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
     Signed-off-by: Steve Dickson <steved@redhat.com>
 
-commit 639b63394c6dd66e06423bfe810366277955c570
+commit 554df6bc8456c6971c1c597f70d3b9131e4e5e11
 Author: Steve Dickson <steved@redhat.com>
-Date:   Thu Feb 18 07:35:00 2010 -0500
+Date:   Tue Sep 28 08:24:16 2010 -0400
 
-    Release 1.2.2
+    Revert "nfs-iostat.py: don't wait for an extra interval when given a count"
     
-    Signed-off-by: Steve Dickson <steved@redhat.com>
+    This reverts commit 837796686ad8f9178c7b6855ada728a53ae511e3.
diff --git a/aclocal/keyutils.m4 b/aclocal/keyutils.m4
new file mode 100644 (file)
index 0000000..84bc112
--- /dev/null
@@ -0,0 +1,11 @@
+dnl Checks for keyutils library and headers
+dnl
+AC_DEFUN([AC_KEYUTILS], [
+
+  dnl Check for libkeyutils; do not add to LIBS if found
+  AC_CHECK_LIB([keyutils], [keyctl_instantiate], [LIBKEYUTILS=-lkeyutils], ,)
+  AC_SUBST(LIBKEYUTILS)
+
+  AC_CHECK_HEADERS([keyutils.h], ,
+                  [AC_MSG_ERROR([keyutils.h header not found.])])
+])dnl
index cfcde2f..4faa923 100644 (file)
@@ -14,4 +14,8 @@ AC_DEFUN([AC_LIBNFSIDMAP], [
                [AC_DEFINE([HAVE_NFS4_SET_DEBUG], 1,
                           [Define to 1 if you have the `nfs4_set_debug' function.])])
 
+  dnl only enable nfsidmap when libnfsidmap supports it
+  AC_CHECK_LIB([nfsidmap], [nfs4_owner_to_uid], [enable_nfsidmap=yes],
+               [enable_nfsidmap=no])
+
 ])dnl
index 3058be6..ca12f9e 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 dnl
-AC_INIT([linux nfs-utils],[1.2.3],[linux-nfs@vger.kernel.org],[nfs-utils])
+AC_INIT([linux nfs-utils],[1.2.4],[linux-nfs@vger.kernel.org],[nfs-utils])
 AC_CANONICAL_BUILD([])
 AC_CANONICAL_HOST([])
 AC_CONFIG_MACRO_DIR(aclocal)
@@ -132,11 +132,20 @@ AC_ARG_ENABLE(mount,
        enable_mount=$enableval,
        enable_mount=yes)
        AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"])
+
+if test "$enable_mount" = yes; then
+       AC_ARG_ENABLE(libmount-mount,
+               [AC_HELP_STRING([--enable-libmount-mount],
+                               [Link mount.nfs with libmount (EXPERIMENTAL)])],
+               enable_libmount=yes,
+               enable_libmount=no)
+fi
+
 AC_ARG_ENABLE(tirpc,
        [AC_HELP_STRING([--enable-tirpc],
                        [enable use of TI-RPC @<:@default=yes@:>@])],
        enable_tirpc=$enableval,
-       enable_tirpc='yes')
+       enable_tirpc='')
 AC_ARG_ENABLE(ipv6,
        [AC_HELP_STRING([--enable-ipv6],
                         [enable support for IPv6 @<:@default=no@:>@])],
@@ -247,6 +256,12 @@ if test "$enable_nfsv4" = yes; then
   dnl check for nfsidmap libraries and headers
   AC_LIBNFSIDMAP
 
+  dnl enable nfsidmap when its support by libnfsidmap
+  AM_CONDITIONAL(CONFIG_NFSIDMAP, [test "$enable_nfsidmap" = "yes"])
+
+  dnl check for the keyutils libraries and headers
+  AC_KEYUTILS
+
   dnl librpcsecgss already has a dependency on libgssapi,
   dnl but we need to make sure we get the right version
   if test "$enable_gss" = yes; then
@@ -279,6 +294,13 @@ AC_SUBST(LIBCRYPT)
 AC_SUBST(LIBBSD)
 AC_SUBST(LIBBLKID)
 
+if test "$enable_libmount" != no; then
+   AC_CHECK_LIB(mount, mnt_context_do_mount, [LIBMOUNT="-lmount"], AC_MSG_ERROR([libmount needed]))
+   AC_CHECK_HEADER(libmount/libmount.h, , AC_MSG_ERROR([Cannot find libmount header file libmount/libmount.h]))
+fi
+AM_CONDITIONAL(CONFIG_LIBMOUNT, [test "$enable_libmount" = "yes"])
+AC_SUBST(LIBMOUNT)
+
 if test "$enable_gss" = yes; then
   dnl 'gss' requires getnameinfo - at least for gssd_proc.c
   AC_CHECK_FUNC([getnameinfo], , [AC_MSG_ERROR([GSSAPI support requires 'getnameinfo' function])])
@@ -435,6 +457,7 @@ AC_CONFIG_FILES([
        utils/mountd/Makefile
        utils/nfsd/Makefile
        utils/nfsstat/Makefile
+       utils/nfsidmap/Makefile
        utils/showmount/Makefile
        utils/statd/Makefile
        tests/Makefile
index dbfc2b1..ba2db8f 100644 (file)
@@ -178,6 +178,7 @@ out_badprefix:
 static int
 init_netmask6(nfs_client *UNUSED(clp), const char *UNUSED(slash))
 {
+       return 0;
 }
 #endif /* IPV6_SUPPORTED */
 
index f528603..4fda30a 100644 (file)
@@ -38,6 +38,7 @@ export_free(nfs_export *exp)
        xfree(exp->m_export.e_sqgids);
        free(exp->m_export.e_mountpoint);
        free(exp->m_export.e_fslocdata);
+       free(exp->m_export.e_uuid);
 
        xfree(exp->m_export.e_hostname);
        xfree(exp);
index 3c55ce7..3e949a1 100644 (file)
 #include "sockaddr.h"
 #include "exportfs.h"
 
-#ifndef HAVE_DECL_AI_ADDRCONFIG
-#define AI_ADDRCONFIG  0
-#endif
-
 /**
  * host_ntop - generate presentation address given a sockaddr
  * @sap: pointer to socket address
@@ -170,7 +166,7 @@ host_addrinfo(const char *hostname)
 #endif
                /* don't return duplicates */
                .ai_protocol    = (int)IPPROTO_UDP,
-               .ai_flags       = AI_ADDRCONFIG | AI_CANONNAME,
+               .ai_flags       = AI_CANONNAME,
        };
        int error;
 
@@ -262,17 +258,19 @@ host_canonname(const struct sockaddr *sap)
  * @sap: pointer to socket address to look up
  *
  * Reverse and forward lookups are performed to ensure the address has
- * proper forward and reverse mappings.
+ * matching forward and reverse mappings.
  *
- * Returns address info structure with ai_canonname filled in, or NULL
- * if no information is available for @sap.  Caller must free the returned
- * structure with freeaddrinfo(3).
+ * Returns addrinfo structure with just the provided address with
+ * ai_canonname filled in. If there is a problem with resolution or
+ * the resolved records don't match up properly then it returns NULL
+ *
+ * Caller must free the returned structure with freeaddrinfo(3).
  */
 __attribute_malloc__
 struct addrinfo *
 host_reliable_addrinfo(const struct sockaddr *sap)
 {
-       struct addrinfo *ai;
+       struct addrinfo *ai, *a;
        char *hostname;
 
        hostname = host_canonname(sap);
@@ -280,9 +278,31 @@ host_reliable_addrinfo(const struct sockaddr *sap)
                return NULL;
 
        ai = host_addrinfo(hostname);
+       if (!ai)
+               goto out_free_hostname;
 
-       free(hostname);
+       /* make sure there's a matching address in the list */
+       for (a = ai; a; a = a->ai_next)
+               if (nfs_compare_sockaddr(a->ai_addr, sap))
+                       break;
+
+       freeaddrinfo(ai);
+       if (!a)
+               goto out_free_hostname;
+
+       /* get addrinfo with just the original address */
+       ai = host_numeric_addrinfo(sap);
+       if (!ai)
+               goto out_free_hostname;
+
+       /* and populate its ai_canonname field */
+       free(ai->ai_canonname);
+       ai->ai_canonname = hostname;
        return ai;
+
+out_free_hostname:
+       free(hostname);
+       return NULL;
 }
 
 /**
index f89c644..2950a90 100644 (file)
@@ -78,7 +78,7 @@ cltsetup(struct nfsctl_client *cltarg, nfs_client *clp)
        str_tolower(cltarg->cl_ident);
 
        j = 0;
-       for (i = 0; i < cltarg->cl_naddr && i < NFSCLNT_ADDRMAX; i++) {
+       for (i = 0; i < clp->m_naddr && i < NFSCLNT_ADDRMAX; i++) {
                const struct sockaddr_in *sin = get_addrlist_in(clp, i);
                if (sin->sin_family == AF_INET)
                        cltarg->cl_addrlist[j++] = sin->sin_addr;
index 3cf1ee8..01e87dd 100644 (file)
@@ -100,6 +100,7 @@ typedef struct mexport {
 } nfs_export;
 
 #define HASH_TABLE_SIZE 1021
+#define DEFAULT_TTL    (30 * 60)
 
 typedef struct _exp_hash_entry {
        nfs_export * p_first;
index bc5ba23..eedc1fe 100644 (file)
@@ -17,4 +17,7 @@ int   weakrandomkey(unsigned char *keyout, int len);
 
 extern int is_mountpoint(char *path);
 
+/* size of the file pointer buffers for rpc procfs files */
+#define RPC_CHAN_BUF_SIZE 32768
+
 #endif /* MISC_H */
index 3db5bec..73f3c20 100644 (file)
 #ifndef _PATH_EXPORTS
 #define _PATH_EXPORTS          "/etc/exports"
 #endif
+#ifndef _PATH_EXPORTS_D
+#define _PATH_EXPORTS_D         "/etc/exports.d"
+#endif
+#ifndef _EXT_EXPORT
+#define _EXT_EXPORT             ".exports"
+#endif
 #ifndef _PATH_IDMAPDCONF
 #define _PATH_IDMAPDCONF       "/etc/idmapd.conf"
 #endif
@@ -89,6 +95,7 @@ struct exportent {
        char *          e_fslocdata;
        char *          e_uuid;
        struct sec_entry e_secinfo[SECFLAVOR_COUNT+1];
+       unsigned int    e_ttl;
 };
 
 struct rmtabent {
@@ -163,6 +170,12 @@ void closeall(int min);
 int                    svctcp_socket (u_long __number, int __reuse);
 int                    svcudp_socket (u_long __number);
 
+/* Misc shared code prototypes */
+size_t  strlcat(char *, const char *, size_t);
+size_t  strlcpy(char *, const char *, size_t);
+ssize_t atomicio(ssize_t (*f) (int, void*, size_t),
+                int, void *, size_t);
+
 
 #define UNUSED(x) UNUSED_ ## x __attribute__((unused))
 
index c5847fa..0b06457 100644 (file)
@@ -31,7 +31,7 @@ struct rpc_dentry {
 
 struct rpc_dtable {
        struct rpc_dentry *entries;
-       int             nproc;
+       rpcproc_t               nproc;
 };
 
 #define dtable_ent(func, vers, arg_type, res_type) \
index 60400b2..05c2fc4 100644 (file)
@@ -5,7 +5,7 @@ libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
                   xlog.c xcommon.c wildmat.c nfsclient.c \
                   nfsexport.c getfh.c nfsctl.c rpc_socket.c getport.c \
                   svc_socket.c cacheio.c closeall.c nfs_mntent.c conffile.c \
-                  svc_create.c
+                  svc_create.c atomicio.c strlcpy.c strlcat.c
 
 MAINTAINERCLEANFILES = Makefile.in
 
diff --git a/support/nfs/atomicio.c b/support/nfs/atomicio.c
new file mode 100644 (file)
index 0000000..5e760e6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2002 Marius Aamodt Eriksen <marius@monkey.org>
+ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+/*
+ * ensure all of data on socket comes through. f==read || f==write
+ */
+ssize_t atomicio(ssize_t(*f) (int, void *, size_t), int fd, void *_s, size_t n)
+{
+       char *s = _s;
+       ssize_t res, pos = 0;
+
+       while ((ssize_t)n > pos) {
+               res = (f) (fd, s + pos, n - pos);
+               switch (res) {
+               case -1:
+                       if (errno == EINTR || errno == EAGAIN)
+                               continue;
+               case 0:
+                       if (pos != 0)
+                               return pos;
+                       return res;
+               default:
+                       pos += res;
+               }
+       }
+       return pos;
+}
index 24640f4..fa0dc6b 100644 (file)
@@ -251,6 +251,7 @@ conf_parse_line(int trans, char *line, size_t sz)
                }
                /* Strip off any blanks before ']' */
                val = line;
+               j=0;
                while (*val && !isblank(*val)) 
                        val++, j++;
                if (*val)
@@ -271,9 +272,9 @@ conf_parse_line(int trans, char *line, size_t sz)
                if (ptr == NULL)
                        return;
                line = ++ptr;
-               while (*ptr && *ptr != '"')
+               while (*ptr && *ptr != '"' && *ptr != ']')
                        ptr++;
-               if (*ptr == '\0') {
+               if (*ptr == '\0' || *ptr == ']') {
                        xlog_warn("config file error: line %d: "
                                "non-matched '\"', ignoring until next section", ln);
                }  else {
index a93941c..c250383 100644 (file)
@@ -107,6 +107,7 @@ static void init_exportent (struct exportent *ee, int fromkernel)
        ee->e_nsquids = 0;
        ee->e_nsqgids = 0;
        ee->e_uuid = NULL;
+       ee->e_ttl = DEFAULT_TTL;
 }
 
 struct exportent *
@@ -141,9 +142,14 @@ getexportent(int fromkernel, int fromexports)
                return NULL;
        }
        first = 0;
-               
-       /* Check for default options */
-       if (exp[0] == '-') {
+
+       /*
+        * Check for default options.  The kernel will never have default
+        * options in /proc/fs/nfs/exports, however due to the initial '-' in
+        * the -test-client- string from the test export we have to check that
+        * we're not reading from the kernel.
+        */
+       if (exp[0] == '-' && !fromkernel) {
                if (parseopts(exp + 1, &def_ee, 0, &has_default_subtree_opts) < 0)
                        return NULL;
                
@@ -332,6 +338,8 @@ dupexportent(struct exportent *dst, struct exportent *src)
                dst->e_mountpoint = strdup(src->e_mountpoint);
        if (src->e_fslocdata)
                dst->e_fslocdata = strdup(src->e_fslocdata);
+       if (src->e_uuid)
+               dst->e_uuid = strdup(src->e_uuid);
        dst->e_hostname = NULL;
 }
 
index a5216fc..a2118a2 100644 (file)
@@ -12,6 +12,7 @@
 #include <string.h>            /* for index */
 #include <ctype.h>             /* for isdigit */
 #include <sys/stat.h>          /* for umask */
+#include <unistd.h>            /* for ftruncate */
 
 #include "nfs_mntent.h"
 #include "nls.h"
@@ -127,9 +128,11 @@ int
 nfs_addmntent (mntFILE *mfp, struct mntent *mnt) {
        char *m1, *m2, *m3, *m4;
        int res;
+       off_t length;
 
        if (fseek (mfp->mntent_fp, 0, SEEK_END))
                return 1;                       /* failure */
+       length = ftell(mfp->mntent_fp);
 
        m1 = mangle(mnt->mnt_fsname);
        m2 = mangle(mnt->mnt_dir);
@@ -143,6 +146,12 @@ nfs_addmntent (mntFILE *mfp, struct mntent *mnt) {
        free(m2);
        free(m3);
        free(m4);
+       if (res >= 0) {
+               res = fflush(mfp->mntent_fp);
+               if (res < 0)
+                       /* Avoid leaving a corrupt mtab file */
+                       ftruncate(fileno(mfp->mntent_fp), length);
+       }
        return (res < 0) ? 1 : 0;
 }
 
index 984c646..f7c27c9 100644 (file)
@@ -32,7 +32,12 @@ rpc_dispatch(struct svc_req *rqstp, SVCXPRT *transp,
                return;
        }
        dtable += (rqstp->rq_vers - 1);
-       if (((int)rqstp->rq_proc) > dtable->nproc) {
+       if (rqstp->rq_proc > dtable->nproc) {
+               svcerr_noproc(transp);
+               return;
+       }
+
+       if (dtable->nproc <= rqstp->rq_proc) {
                svcerr_noproc(transp);
                return;
        }
diff --git a/support/nfs/strlcat.c b/support/nfs/strlcat.c
new file mode 100644 (file)
index 0000000..daedd7a
--- /dev/null
@@ -0,0 +1,76 @@
+/*     $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $     */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * 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. The name of the author may not 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 AUTHOR 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left).  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(char *dst,
+       const char *src,
+       size_t siz)
+{
+       register char *d = dst;
+       register const char *s = src;
+       register size_t n = siz;
+       size_t dlen;
+
+       /* Find the end of dst and adjust bytes left but don't go past end */
+       while (n-- != 0 && *d != '\0')
+               d++;
+       dlen = d - dst;
+       n = siz - dlen;
+
+       if (n == 0)
+               return(dlen + strlen(s));
+       while (*s != '\0') {
+               if (n != 1) {
+                       *d++ = *s;
+                       n--;
+               }
+               s++;
+       }
+       *d = '\0';
+
+       return(dlen + (s - src));       /* count does not include NUL */
+}
diff --git a/support/nfs/strlcpy.c b/support/nfs/strlcpy.c
new file mode 100644 (file)
index 0000000..a2653ee
--- /dev/null
@@ -0,0 +1,72 @@
+/*     $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $     */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * 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. The name of the author may not 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 AUTHOR 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst,
+       const char *src,
+       size_t siz)
+{
+       register char *d = dst;
+       register const char *s = src;
+       register size_t n = siz;
+
+       /* Copy as many bytes as will fit */
+       if (n != 0 && --n != 0) {
+               do {
+                       if ((*d++ = *s++) == 0)
+                               break;
+               } while (--n != 0);
+       }
+
+       /* Not enough room in dst, add NUL and traverse rest of src */
+       if (n == 0) {
+               if (siz != 0)
+                       *d = '\0';              /* NUL-terminate dst */
+               while (*s++)
+                       ;
+       }
+
+       return(s - src - 1);    /* count does not include NUL */
+}
index 59ba505..b3f75ed 100644 (file)
@@ -27,6 +27,7 @@
 #include <memory.h>
 #include <signal.h>
 #include <unistd.h>
+#include <errno.h>
 #include <netdb.h>
 
 #include <netinet/in.h>
 #include "tcpwrapper.h"
 #endif
 
+#include "sockaddr.h"
 #include "rpcmisc.h"
 #include "xlog.h"
 
 #ifdef HAVE_LIBTIRPC
 
+#define SVC_CREATE_XPRT_CACHE_SIZE     (8)
+static SVCXPRT *svc_create_xprt_cache[SVC_CREATE_XPRT_CACHE_SIZE] = { NULL, };
+
+/*
+ * Cache an SVC xprt, in case there are more programs or versions to
+ * register against it.
+ */
+static void
+svc_create_cache_xprt(SVCXPRT *xprt)
+{
+       unsigned int i;
+
+       /* Check if we've already got this one... */
+       for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++)
+               if (svc_create_xprt_cache[i] == xprt)
+                       return;
+
+       /* No, we don't.  Cache it. */
+       for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++)
+               if (svc_create_xprt_cache[i] == NULL) {
+                       svc_create_xprt_cache[i] = xprt;
+                       return;
+               }
+
+       xlog(L_ERROR, "%s: Failed to cache an xprt", __func__);
+}
+
+/*
+ * Find a previously cached SVC xprt structure with the given bind address
+ * and transport semantics.
+ *
+ * Returns pointer to a cached SVC xprt.
+ *
+ * If no matching SVC XPRT can be found, NULL is returned.
+ */
+static SVCXPRT *
+svc_create_find_xprt(const struct sockaddr *bindaddr, const struct netconfig *nconf)
+{
+       unsigned int i;
+
+       for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++) {
+               SVCXPRT *xprt = svc_create_xprt_cache[i];
+               struct sockaddr *sap;
+
+               if (xprt == NULL)
+                       continue;
+               if (strcmp(nconf->nc_netid, xprt->xp_netid) != 0)
+                       continue;
+               sap = (struct sockaddr *)xprt->xp_ltaddr.buf;
+               if (!nfs_compare_sockaddr(bindaddr, sap))
+                       continue;
+               return xprt;
+       }
+       return NULL;
+}
+
 /*
  * Set up an appropriate bind address, given @port and @nconf.
  *
@@ -98,17 +156,113 @@ svc_create_bindaddr(struct netconfig *nconf, const uint16_t port)
        return ai;
 }
 
+/*
+ * Create a listener socket on a specific bindaddr, and set
+ * special socket options to allow it to share the same port
+ * as other listeners.
+ *
+ * Returns an open, bound, and possibly listening network
+ * socket on success.
+ *
+ * Otherwise returns -1 if some error occurs.
+ */
+static int
+svc_create_sock(const struct sockaddr *sap, socklen_t salen,
+               struct netconfig *nconf)
+{
+       int fd, type, protocol;
+       int one = 1;
+
+       switch(nconf->nc_semantics) {
+       case NC_TPI_CLTS:
+               type = SOCK_DGRAM;
+               break;
+       case NC_TPI_COTS_ORD:
+               type = SOCK_STREAM;
+               break;
+       default:
+               xlog(D_GENERAL, "%s: Unrecognized bind address semantics: %u",
+                       __func__, nconf->nc_semantics);
+               return -1;
+       }
+
+       if (strcmp(nconf->nc_proto, NC_UDP) == 0)
+               protocol = (int)IPPROTO_UDP;
+       else if (strcmp(nconf->nc_proto, NC_TCP) == 0)
+               protocol = (int)IPPROTO_TCP;
+       else {
+               xlog(D_GENERAL, "%s: Unrecognized bind address protocol: %s",
+                       __func__, nconf->nc_proto);
+               return -1;
+       }
+
+       fd = socket((int)sap->sa_family, type, protocol);
+       if (fd == -1) {
+               xlog(L_ERROR, "Could not make a socket: (%d) %m",
+                       errno);
+               return -1;
+       }
+
+#ifdef IPV6_SUPPORTED
+       if (sap->sa_family == AF_INET6) {
+               if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
+                               &one, sizeof(one)) == -1) {
+                       xlog(L_ERROR, "Failed to set IPV6_V6ONLY: (%d) %m",
+                               errno);
+                       (void)close(fd);
+                       return -1;
+               }
+       }
+#endif /* IPV6_SUPPORTED */
+
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+                      &one, sizeof(one)) == -1) {
+               xlog(L_ERROR, "Failed to set SO_REUSEADDR: (%d) %m",
+                       errno);
+               (void)close(fd);
+               return -1;
+       }
+
+       if (bind(fd, sap, salen) == -1) {
+               xlog(L_ERROR, "Could not bind socket: (%d) %m",
+                       errno);
+               (void)close(fd);
+               return -1;
+       }
+
+       if (nconf->nc_semantics == NC_TPI_COTS_ORD)
+               if (listen(fd, SOMAXCONN) == -1) {
+                       xlog(L_ERROR, "Could not listen on socket: (%d) %m",
+                               errno);
+                       (void)close(fd);
+                       return -1;
+               }
+
+       return fd;
+}
+
+/*
+ * The simple case is allowing the TI-RPC library to create a
+ * transport itself, given just the bind address and transport
+ * semantics.
+ *
+ * Our local xprt cache is ignored in this path, since the
+ * caller is not interested in sharing listeners or ports, and
+ * the library automatically avoids ports already in use.
+ *
+ * Returns the count of started listeners (one or zero).
+ */
 static unsigned int
-svc_create_nconf(const char *name, const rpcprog_t program,
+svc_create_nconf_rand_port(const char *name, const rpcprog_t program,
                const rpcvers_t version,
                void (*dispatch)(struct svc_req *, SVCXPRT *),
-               const uint16_t port, struct netconfig *nconf)
+               struct netconfig *nconf)
 {
        struct t_bind bindaddr;
        struct addrinfo *ai;
        SVCXPRT *xprt;
 
-       ai = svc_create_bindaddr(nconf, port);
+       ai = svc_create_bindaddr(nconf, 0);
        if (ai == NULL)
                return 0;
 
@@ -119,7 +273,7 @@ svc_create_nconf(const char *name, const rpcprog_t program,
        freeaddrinfo(ai);
        if (xprt == NULL) {
                xlog(D_GENERAL, "Failed to create listener xprt "
-                               "(%s, %u, %s)", name, version, nconf->nc_netid);
+                       "(%s, %u, %s)", name, version, nconf->nc_netid);
                return 0;
        }
 
@@ -133,6 +287,93 @@ svc_create_nconf(const char *name, const rpcprog_t program,
        return 1;
 }
 
+/*
+ * If a port is specified on the command line, that port value will be
+ * the same for all listeners created here.  Create each listener
+ * socket in advance and set SO_REUSEADDR, rather than allowing the
+ * RPC library to create the listeners for us on a randomly chosen
+ * port via svc_tli_create(RPC_ANYFD).
+ *
+ * Some callers want to listen for more than one RPC version using the
+ * same port number.  For example, mountd could want to listen for MNT
+ * version 1, 2, and 3 requests.  This means mountd must use the same
+ * set of listener sockets for multiple RPC versions, since, on one
+ * system, you can't have two listener sockets with the exact same
+ * bind address (and port) and transport protocol.
+ *
+ * To accomplish this, this function caches xprts as they are created.
+ * This cache is checked to see if a previously created xprt can be
+ * used, before creating a new xprt for this [program, version].  If
+ * there is a cached xprt with the same bindaddr and transport
+ * semantics, we simply register the new version with that xprt,
+ * rather than creating a fresh xprt for it.
+ *
+ * The xprt cache implemented here is local to a process.  Two
+ * separate RPC daemons can not share a set of listeners.
+ *
+ * Returns the count of started listeners (one or zero).
+ */
+static unsigned int
+svc_create_nconf_fixed_port(const char *name, const rpcprog_t program,
+               const rpcvers_t version,
+               void (*dispatch)(struct svc_req *, SVCXPRT *),
+               const uint16_t port, struct netconfig *nconf)
+{
+       struct addrinfo *ai;
+       SVCXPRT *xprt;
+
+       ai = svc_create_bindaddr(nconf, port);
+       if (ai == NULL)
+               return 0;
+
+       xprt = svc_create_find_xprt(ai->ai_addr, nconf);
+       if (xprt == NULL) {
+               int fd;
+
+               fd = svc_create_sock(ai->ai_addr, ai->ai_addrlen, nconf);
+               if (fd == -1)
+                       goto out_free;
+
+               xprt = svc_tli_create(fd, nconf, NULL, 0, 0);
+               if (xprt == NULL) {
+                       xlog(D_GENERAL, "Failed to create listener xprt "
+                               "(%s, %u, %s)", name, version, nconf->nc_netid);
+                       (void)close(fd);
+                       goto out_free;
+               }
+       }
+
+       if (!svc_reg(xprt, program, version, dispatch, nconf)) {
+               /* svc_reg(3) destroys @xprt in this case */
+               xlog(D_GENERAL, "Failed to register (%s, %u, %s)",
+                               name, version, nconf->nc_netid);
+               goto out_free;
+       }
+
+       svc_create_cache_xprt(xprt);
+
+       freeaddrinfo(ai);
+       return 1;
+
+out_free:
+       freeaddrinfo(ai);
+       return 0;
+}
+
+static unsigned int
+svc_create_nconf(const char *name, const rpcprog_t program,
+               const rpcvers_t version,
+               void (*dispatch)(struct svc_req *, SVCXPRT *),
+               const uint16_t port, struct netconfig *nconf)
+{
+       if (port != 0)
+               return svc_create_nconf_fixed_port(name, program,
+                       version, dispatch, port, nconf);
+
+       return svc_create_nconf_rand_port(name, program,
+                       version, dispatch, nconf);
+}
+
 /**
  * nfs_svc_create - start up RPC svc listeners
  * @name: C string containing name of new service
@@ -145,8 +386,7 @@ svc_create_nconf(const char *name, const rpcprog_t program,
  * the RPC dispatcher.  Returns the number of started network transports.
  */
 unsigned int
-nfs_svc_create(__attribute__((unused)) char *name,
-               const rpcprog_t program, const rpcvers_t version,
+nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version,
                void (*dispatch)(struct svc_req *, SVCXPRT *),
                const uint16_t port)
 {
index f4baeb9..98b47bf 100644 (file)
@@ -126,7 +126,7 @@ exact_error_check(const ssize_t len, const size_t buflen)
  * containing an appropriate pathname, or NULL if an error
  * occurs.  Caller must free the returned result with free(3).
  */
-__attribute_malloc__
+__attribute__((__malloc__))
 static char *
 nsm_make_record_pathname(const char *directory, const char *hostname)
 {
@@ -174,7 +174,7 @@ nsm_make_record_pathname(const char *directory, const char *hostname)
  * containing an appropriate pathname, or NULL if an error
  * occurs.  Caller must free the returned result with free(3).
  */
-__attribute_malloc__
+__attribute__((__malloc__))
 static char *
 nsm_make_pathname(const char *directory)
 {
@@ -204,7 +204,7 @@ nsm_make_pathname(const char *directory)
  * containing an appropriate pathname, or NULL if an error
  * occurs.  Caller must free the returned result with free(3).
  */
-__attribute_malloc__
+__attribute__((__malloc__))
 static char *
 nsm_make_temp_pathname(const char *pathname)
 {
@@ -421,7 +421,7 @@ nsm_drop_privileges(const int pidfd)
         */
         if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
                 xlog(L_ERROR, "prctl(PR_SET_KEEPCAPS) failed: %m");
-               return 0;
+               return false;
        }
 
        if (setgroups(0, NULL) == -1) {
@@ -568,9 +568,8 @@ nsm_retire_monitored_hosts(void)
 
        while ((de = readdir(dir)) != NULL) {
                char *src, *dst;
+               struct stat stb;
 
-               if (de->d_type != (unsigned char)DT_REG)
-                       continue;
                if (de->d_name[0] == '.')
                        continue;
 
@@ -580,6 +579,20 @@ nsm_retire_monitored_hosts(void)
                        continue;
                }
 
+               /* NB: not all file systems fill in d_type correctly */
+               if (lstat(src, &stb) == -1) {
+                       xlog_warn("Bad monitor file %s, skipping: %m",
+                                       de->d_name);
+                       free(src);
+                       continue;
+               }
+               if (!S_ISREG(stb.st_mode)) {
+                       xlog(D_GENERAL, "Skipping non-regular file %s",
+                                       de->d_name);
+                       free(src);
+                       continue;
+               }
+
                dst = nsm_make_record_pathname(NSM_NOTIFY_DIR, de->d_name);
                if (dst == NULL) {
                        free(src);
@@ -634,7 +647,7 @@ nsm_priv_to_hex(const char *priv, char *buf, const size_t buflen)
 /*
  * Returns the length in bytes of the created record.
  */
-__attribute_noinline__
+__attribute__((__noinline__))
 static size_t
 nsm_create_monitor_record(char *buf, const size_t buflen,
                const struct sockaddr *sap, const struct mon *m)
@@ -784,7 +797,7 @@ out:
        return result;
 }
 
-__attribute_noinline__
+__attribute__((__noinline__))
 static _Bool
 nsm_parse_line(char *line, struct sockaddr_in *sin, struct mon *m)
 {
@@ -846,7 +859,7 @@ nsm_read_line(const char *hostname, const time_t timestamp, char *line,
 }
 
 /*
- * Given a filename, reads data from a file under NSM_MONITOR_DIR
+ * Given a filename, reads data from a file under "directory"
  * and invokes @func so caller can populate their in-core
  * database with this data.
  */
@@ -863,10 +876,15 @@ nsm_load_host(const char *directory, const char *filename, nsm_populate_t func)
        if (path == NULL)
                goto out_err;
 
-       if (stat(path, &stb) == -1) {
+       if (lstat(path, &stb) == -1) {
                xlog(L_ERROR, "Failed to stat %s: %m", path);
                goto out_freepath;
        }
+       if (!S_ISREG(stb.st_mode)) {
+               xlog(D_GENERAL, "Skipping non-regular file %s",
+                               path);
+               goto out_freepath;
+       }
 
        f = fopen(path, "r");
        if (f == NULL) {
@@ -913,8 +931,6 @@ nsm_load_dir(const char *directory, nsm_populate_t func)
        }
 
        while ((de = readdir(dir)) != NULL) {
-               if (de->d_type != (unsigned char)DT_REG)
-                       continue;
                if (de->d_name[0] == '.')
                        continue;
 
index 0d1159a..0fa3422 100644 (file)
@@ -205,7 +205,7 @@ nsm_client_get_rpcclient(const char *node)
 {
        unsigned short          port;
        struct addrinfo         *ai;
-       struct addrinfo         hints = { .ai_flags     = AI_ADDRCONFIG };
+       struct addrinfo         hints = { };
        int                     err;
        CLIENT                  *client = NULL;
 
index 8665183..a0ea116 100644 (file)
@@ -4,6 +4,9 @@ OPTDIRS =
 
 if CONFIG_NFSV4
 OPTDIRS += idmapd
+if CONFIG_NFSIDMAP
+OPTDIRS += nfsidmap
+endif
 endif
 
 if CONFIG_GSS
index b78957f..b107c7c 100644 (file)
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include <netdb.h>
 #include <errno.h>
+#include <dirent.h>
 
 #include "sockaddr.h"
 #include "misc.h"
@@ -41,6 +42,7 @@ static void   error(nfs_export *exp, int err);
 static void    usage(const char *progname);
 static void    validate_export(nfs_export *exp);
 static int     matchhostname(const char *hostname1, const char *hostname2);
+static void    export_d_read(const char *dname);
 
 int
 main(int argc, char **argv)
@@ -127,8 +129,10 @@ main(int argc, char **argv)
                        return 0;
                }
        }
-       if (f_export && ! f_ignore)
+       if (f_export && ! f_ignore) {
                export_read(_PATH_EXPORTS);
+               export_d_read(_PATH_EXPORTS_D);
+       }
        if (f_export) {
                if (f_all)
                        export_all(f_verbose);
@@ -246,7 +250,7 @@ static void
 exportfs(char *arg, char *options, int verbose)
 {
        struct exportent *eep;
-       nfs_export      *exp;
+       nfs_export      *exp = NULL;
        struct addrinfo *ai = NULL;
        char            *path;
        char            *hname = arg;
@@ -485,6 +489,59 @@ out:
        return result;
 }
 
+/* Based on mnt_table_parse_dir() in
+   util-linux-ng/shlibs/mount/src/tab_parse.c */
+static void
+export_d_read(const char *dname)
+{
+       int n = 0, i;
+       struct dirent **namelist = NULL;
+
+
+       n = scandir(dname, &namelist, NULL, versionsort);
+       if (n < 0)
+               xlog(L_NOTICE, "scandir %s: %s\n", dname, strerror(errno));
+       else if (n == 0)
+               return;
+
+       for (i = 0; i < n; i++) {
+               struct dirent *d = namelist[i];
+               size_t namesz;
+               char fname[PATH_MAX + 1];
+               int fname_len;
+
+
+               if (d->d_type != DT_UNKNOWN 
+                   && d->d_type != DT_REG
+                   && d->d_type != DT_LNK)
+                       continue;
+               if (*d->d_name == '.')
+                       continue;
+
+#define _EXT_EXPORT_SIZ   (sizeof(_EXT_EXPORT) - 1)
+               namesz = strlen(d->d_name);
+               if (!namesz 
+                   || namesz < _EXT_EXPORT_SIZ + 1
+                   || strcmp(d->d_name + (namesz - _EXT_EXPORT_SIZ),
+                             _EXT_EXPORT))
+                       continue;
+
+               fname_len = snprintf(fname, PATH_MAX +1, "%s/%s", dname, d->d_name);
+               if (fname_len > PATH_MAX) {
+                       xlog(L_WARNING, "Too long file name: %s in %s\n", d->d_name, dname);
+                       continue;
+               }
+
+               export_read(fname);
+       }
+               
+       for (i = 0; i < n; i++)
+               free(namelist[i]);
+       free(namelist);
+
+       return;
+}
+
 static char
 dumpopt(char c, char *fmt, ...)
 {
index 089f75b..364f247 100644 (file)
@@ -37,11 +37,15 @@ when a client sends an NFS MOUNT request.
 .PP
 Normally the master export table is initialized with the contents of
 .I /etc/exports
+and files under
+.I /etc/exports.d
 by invoking
 .BR "exportfs -a" .
 However, a system administrator can choose to add or delete
 exports without modifying
 .I /etc/exports
+or files under
+.I /etc/exports.d
 by using the
 .B exportfs
 command.
@@ -92,17 +96,24 @@ Specify a list of export options in the same manner as in
 .B -i
 Ignore the
 .I /etc/exports
-file.  Only default options and options given on the command line are used.
+file and files under
+.I /etc/exports.d
+directory.  Only default options and options given on the command line are used.
 .TP
 .B -r
 Reexport all directories, synchronizing
 .I /var/lib/nfs/etab
 with
-.IR /etc/exports .
+.IR /etc/exports 
+and files under 
+.IR /etc/exports.d .
 This option removes entries in
 .I /var/lib/nfs/etab
 which have been deleted from
-.I /etc/exports, and removes any entries from the
+.I /etc/exports
+or files under
+.IR /etc/exports.d , 
+and removes any entries from the
 kernel export table which are no longer valid.
 .TP
 .B -u
@@ -130,6 +141,8 @@ when adding new entries to the export table.  When using
 .BR "exportfs -a" ,
 all exports listed in
 .I /etc/exports
+and files under
+.I /etc/exports.d
 are added to
 .IR /var/lib/nfs/etab .
 The kernel's export table is also updated as needed.
@@ -149,7 +162,9 @@ several sources.
 The default export options are
 .BR sync,ro,root_squash,wdelay .
 These can be overridden by entries in
-.IR /etc/exports .
+.IR /etc/exports 
+or files under
+.IR /etc/exports.d .
 .PP
 A system administrator may override options from these sources using the
 .B -o
@@ -188,6 +203,8 @@ to display the export options for each export.
 .SH EXAMPLES
 The following adds all directories listed in
 .I /etc/exports
+and files under
+.I /etc/exports.d
 to
 .I /var/lib/nfs/etab
 and pushes the resulting export entries into the kernel:
@@ -215,7 +232,9 @@ directory:
 .fi
 .PP
 To unexport all exports listed in
-.IR /etc/exports :
+.IR /etc/exports 
+and files under
+.IR /etc/exports.d :
 .PP
 .nf
 .B "# exportfs -au
@@ -238,6 +257,13 @@ if they themselves are no longer valid they will be removed.
 .I /etc/exports
 input file listing exports, export options, and access control lists
 .TP 2.5i
+.I /etc/exports.d
+directory where extra input files are stored.
+.B Note:
+only files that end with 
+.I .exports
+are used.
+.TP 2.5i
 .I /var/lib/nfs/etab
 master table of exports
 .TP 2.5i
index c726dd9..b202583 100644 (file)
@@ -45,22 +45,11 @@ or restart the NFS server.
 .SS Machine Name Formats
 NFS clients may be specified in a number of ways:
 .IP "single host
-This is the most common format. You may specify a host either by an
+You may specify a host either by an
 abbreviated name recognized be the resolver, the fully qualified domain
-name, or an IP address.
-.IP "netgroups
-NIS netgroups may be given as
-.IR @group .
-Only the host part of each
-netgroup members is consider in checking for membership.  Empty host
-parts or those containing a single dash (\-) are ignored.
-.IP "wildcards
-Machine names may contain the wildcard characters \fI*\fR and \fI?\fR.
-This can be used to make the \fIexports\fR file more compact; for instance,
-\fI*.cs.foo.edu\fR matches all hosts in the domain
-\fIcs.foo.edu\fR.  As these characters also match the dots in a domain
-name, the given pattern will also match all hosts within any subdomain
-of \fIcs.foo.edu\fR.
+name, an IPv4 address, or an IPv6 address. IPv6 addresses must not be
+inside square brackets in /etc/exports lest they be confused with
+character-class wildcard matches.
 .IP "IP networks
 You can also export directories to all hosts on an IP (sub-) network
 simultaneously. This is done by specifying an IP address and netmask pair
@@ -69,9 +58,28 @@ as
 where the netmask can be specified in dotted-decimal format, or as a
 contiguous mask length.
 For example, either `/255.255.252.0' or `/22' appended
-to the network base IPv4 address results in identical subnetworks with 10 bits of
-host. Wildcard characters generally do not work on IP addresses, though they
+to the network base IPv4 address results in identical subnetworks with 10 bits
+of host. IPv6 addresses must use a contiguous mask length and must not be inside square brackets to avoid confusion with character-class wildcards. Wildcard characters generally do not work on IP addresses, though they
 may work by accident when reverse DNS lookups fail.
+.IP "wildcards
+Machine names may contain the wildcard characters \fI*\fR and \fI?\fR, or may contain character class lists within [square brackets].
+This can be used to make the \fIexports\fR file more compact; for instance,
+\fI*.cs.foo.edu\fR matches all hosts in the domain
+\fIcs.foo.edu\fR.  As these characters also match the dots in a domain
+name, the given pattern will also match all hosts within any subdomain
+of \fIcs.foo.edu\fR.
+.IP "netgroups
+NIS netgroups may be given as
+.IR @group .
+Only the host part of each
+netgroup members is consider in checking for membership.  Empty host
+parts or those containing a single dash (\-) are ignored.
+.IP "anonymous
+This is specified by a single
+.I *
+character (not to be confused with the
+.I wildcard
+entry above) and will match all clients.
 '''.TP
 '''.B =public
 '''This is a special ``hostname'' that identifies the given directory name
@@ -92,6 +100,12 @@ may work by accident when reverse DNS lookups fail.
 '''.B \-\-public\-root
 '''option. Multiple specifications of a public root will be ignored.
 .PP
+If a client matches more than one of the specifications above, then
+the first match from the above list order takes precedence - regardless of
+the order they appear on the export line. However, if a client matches
+more than one of the same type of specification (e.g. two netgroups),
+then the first match from the order they appear on the export line takes
+precedence.
 .SS RPCSEC_GSS security
 You may use the special strings "gss/krb5", "gss/krb5i", or "gss/krb5p"
 to restrict access to clients using rpcsec_gss security.  However, this
@@ -145,7 +159,9 @@ storage (see
 .IR async
 above).
 
-In releases of nfs-utils up to and including 1.0.0, this option was the
+In releases of nfs-utils up to and including 1.0.0, the
+.I async 
+option was the
 default.  In all releases after 1.0.0,
 .I sync
 is the default, and
@@ -375,20 +391,6 @@ If the client asks for alternative locations for the export point, it
 will be given this list of alternatives. (Note that actual replication
 of the filesystem must be handled elsewhere.)
 
-.TP
-.IR refer= path@host[+host][:path@host[+host]]
-A client referencing the export point will be directed to choose from
-the given list an alternative location for the filesystem.
-(Note that the server must have a mountpoint here, though a different
-filesystem is not required; so, for example,
-.IR "mount --bind" " /path /path"
-is sufficient.)
-.TP
-.IR replicas= path@host[+host][:path@host[+host]]
-If the client asks for alternative locations for the export point, it
-will be given this list of alternatives. (Note that actual replication
-of the filesystem must be handled elsewhere.)
-
 .SS User ID Mapping
 .PP
 .B nfsd
@@ -456,6 +458,24 @@ export entry for
 .B /home/joe
 in the example section below, which maps all requests to uid 150 (which
 is supposedly that of user joe).
+.SS Extra Export Tables
+After reading 
+.I /etc/exports 
+.B exportfs
+reads files under 
+.I /etc/exports.d. 
+directory as extra export tables.
+.B exportfs
+regards only a file which name is ended with 
+.I .exports
+and
+not started with 
+.I . 
+as an extra export file. A file which name
+is not met this condition is just ignored.
+The format for extra export tables is the same as 
+.I /etc/exports
+.
 .IP
 .SH EXAMPLE
 .PP
@@ -468,6 +488,8 @@ is supposedly that of user joe).
 /home/joe       pc001(rw,all_squash,anonuid=150,anongid=100)
 /pub            *(ro,insecure,all_squash)
 /srv/www        \-sync,rw server @trusted @external(ro)
+/foo            2001:db8:9:e54::/64(rw) 192.0.2.0/24(rw)
+/build          buildhost[0-9].local.domain(rw)
 '''/pub/private    (noaccess)
 .fi
 .PP
@@ -483,7 +505,9 @@ option in this entry also allows clients with NFS implementations that
 don't use a reserved port for NFS.
 The sixth line exports a directory read-write to the machine 'server'
 as well as the `@trusted' netgroup, and read-only to netgroup `@external',
-all three mounts with the `sync' option enabled.
+all three mounts with the `sync' option enabled. The seventh line exports
+a directory to both an IPv6 and an IPv4 subnet. The eighth line demonstrates
+a character class wildcard match.
 ''' The last line denies all NFS clients
 '''access to the private directory.
 '''.SH CAVEATS
@@ -501,6 +525,7 @@ all three mounts with the `sync' option enabled.
 '''entry.
 .SH FILES
 /etc/exports
+/etc/exports.d
 .SH SEE ALSO
 .BR exportfs (8),
 .BR netgroup (5),
index 95a2bd0..d7888ad 100644 (file)
@@ -51,7 +51,9 @@ svcgssd_SOURCES = \
        svcgssd_main_loop.c \
        svcgssd_mech2file.c \
        svcgssd_proc.c \
+       svcgssd_krb5.c \
        \
+       svcgssd_krb5.h \
        svcgssd.h
 
 svcgssd_LDADD = \
index 8fe1e9b..0e327b0 100644 (file)
@@ -138,6 +138,83 @@ display_status_1(char *m, u_int32_t code, int type, const gss_OID mech)
        }
 }
 #endif
+static char *
+gss_display_error(OM_uint32 status)
+{
+               char *error = NULL;
+
+               switch(status) {
+               case GSS_S_COMPLETE: 
+                       error = "GSS_S_COMPLETE";
+                       break;
+               case GSS_S_CALL_INACCESSIBLE_READ: 
+                       error = "GSS_S_CALL_INACCESSIBLE_READ";
+                       break;
+               case GSS_S_CALL_INACCESSIBLE_WRITE:
+                       error = "GSS_S_CALL_INACCESSIBLE_WRITE";
+                       break;
+               case GSS_S_CALL_BAD_STRUCTURE:
+                       error = "GSS_S_CALL_BAD_STRUCTURE";
+                       break;
+               case  GSS_S_BAD_MECH:
+                       error = "GSS_S_BAD_MECH";
+                       break;
+               case  GSS_S_BAD_NAME:
+                       error = "GSS_S_BAD_NAME";
+                       break;
+               case  GSS_S_BAD_NAMETYPE:
+                       error = "GSS_S_BAD_NAMETYPE";
+                       break;
+               case  GSS_S_BAD_BINDINGS:
+                       error = "GSS_S_BAD_BINDINGS";
+                       break;
+               case  GSS_S_BAD_STATUS:
+                       error = "GSS_S_BAD_STATUS";
+                       break;
+               case  GSS_S_BAD_SIG:
+                       error = "GSS_S_BAD_SIG";
+                       break;
+               case  GSS_S_NO_CRED:
+                       error = "GSS_S_NO_CRED";
+                       break;
+               case  GSS_S_NO_CONTEXT:
+                       error = "GSS_S_NO_CONTEXT";
+                       break;
+               case  GSS_S_DEFECTIVE_TOKEN:
+                       error = "GSS_S_DEFECTIVE_TOKEN";
+                       break;
+               case  GSS_S_DEFECTIVE_CREDENTIAL:
+                       error = "GSS_S_DEFECTIVE_CREDENTIAL";
+                       break;
+               case  GSS_S_CREDENTIALS_EXPIRED:
+                       error = "GSS_S_CREDENTIALS_EXPIRED";
+                       break;
+               case  GSS_S_CONTEXT_EXPIRED:
+                       error = "GSS_S_CONTEXT_EXPIRED";
+                       break;
+               case  GSS_S_FAILURE:
+                       error = "GSS_S_FAILURE";
+                       break;
+               case  GSS_S_BAD_QOP:
+                       error = "GSS_S_BAD_QOP";
+                       break;
+               case  GSS_S_UNAUTHORIZED:
+                       error = "GSS_S_UNAUTHORIZED";
+                       break;
+               case  GSS_S_UNAVAILABLE:
+                       error = "GSS_S_UNAVAILABLE";
+                       break;
+               case  GSS_S_DUPLICATE_ELEMENT:
+                       error = "GSS_S_DUPLICATE_ELEMENT";
+                       break;
+               case  GSS_S_NAME_NOT_MN:
+                       error = "GSS_S_NAME_NOT_MN";
+                       break;
+               default:
+                       error = "Not defined";
+               }
+       return error;
+}
 
 static void
 display_status_2(char *m, u_int32_t major, u_int32_t minor, const gss_OID mech)
@@ -175,8 +252,9 @@ display_status_2(char *m, u_int32_t major, u_int32_t minor, const gss_OID mech)
 
        if (major == GSS_S_CREDENTIALS_EXPIRED)
                msg_verbosity = 1;
-       printerr(msg_verbosity, "ERROR: GSS-API: error in %s(): %s - %s\n",
-                m, maj, min);
+
+       printerr(msg_verbosity, "ERROR: GSS-API: error in %s(): %s (%s) - %s\n",
+                m, gss_display_error(major), maj, min);
 
        if (maj_gss_buf.length != 0)
                (void) gss_release_buffer(&min_stat1, &maj_gss_buf);
@@ -199,20 +277,25 @@ gssd_acquire_cred(char *server_name, const gss_OID oid)
        u_int32_t ignore_maj_stat, ignore_min_stat;
        gss_buffer_desc pbuf;
 
-       name.value = (void *)server_name;
-       name.length = strlen(server_name);
+       /* If server_name is NULL, get cred for GSS_C_NO_NAME */
+       if (server_name == NULL) {
+               target_name = GSS_C_NO_NAME;
+       } else {
+               name.value = (void *)server_name;
+               name.length = strlen(server_name);
 
-       maj_stat = gss_import_name(&min_stat, &name,
-                       oid,
-                       &target_name);
+               maj_stat = gss_import_name(&min_stat, &name,
+                               oid,
+                               &target_name);
 
-       if (maj_stat != GSS_S_COMPLETE) {
-               pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid);
-               return (FALSE);
+               if (maj_stat != GSS_S_COMPLETE) {
+                       pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid);
+                       return (FALSE);
+               }
        }
 
-       maj_stat = gss_acquire_cred(&min_stat, target_name, 0,
-                       GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
+       maj_stat = gss_acquire_cred(&min_stat, target_name, GSS_C_INDEFINITE,
+                       GSS_C_NO_OID_SET, GSS_C_ACCEPT,
                        &gssd_creds, NULL, NULL);
 
        if (maj_stat != GSS_S_COMPLETE) {
index 0a23cd6..073379d 100644 (file)
@@ -53,6 +53,8 @@ To be more consistent with other implementations, we now look for
 specific keytab entries.  The search order for keytabs to be used
 for "machine credentials" is now:
 .br
+  <HOSTNAME>$@<REALM>
+.br
   root/<hostname>@<REALM>
 .br
   nfs/<hostname>@<REALM>
@@ -64,6 +66,9 @@ for "machine credentials" is now:
   nfs/<anyname>@<REALM>
 .br
   host/<anyname>@<REALM>
+.IP
+If this search order does not use the correct key then provide a
+keytab file that contains only correct keys.
 .TP
 .B -p path
 Tells
index c301d46..41328c9 100644 (file)
@@ -1245,7 +1245,7 @@ handle_gssd_upcall(struct clnt_info *clp)
                        goto out;
                if (sscanf(p, "enctypes=%s", enctypes) != 1) {
                        printerr(0, "WARNING: handle_gssd_upcall: "
-                                   "failed to parse target name "
+                                   "failed to parse encryption types "
                                    "in upcall string '%s'\n", lbuf);
                        goto out;
                }
index f071600..4b13fa1 100644 (file)
@@ -768,6 +768,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
        krb5_error_code code;
        char **realmnames = NULL;
        char myhostname[NI_MAXHOST], targethostname[NI_MAXHOST];
+       char myhostad[NI_MAXHOST+1];
        int i, j, retval;
        char *default_realm = NULL;
        char *realm;
@@ -789,6 +790,14 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
                printerr(1, "%s while getting local hostname\n", k5err);
                goto out;
        }
+
+       /* Compute the active directory machine name HOST$ */
+       strcpy(myhostad, myhostname);
+       for (i = 0; myhostad[i] != 0; ++i)
+               myhostad[i] = toupper(myhostad[i]);
+       myhostad[i] = '$';
+       myhostad[i+1] = 0;
+
        retval = get_full_hostname(myhostname, myhostname, sizeof(myhostname));
        if (retval)
                goto out;
@@ -833,32 +842,47 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
                if (strcmp(realm, default_realm) == 0)
                        tried_default = 1;
                for (j = 0; svcnames[j] != NULL; j++) {
-                       code = krb5_build_principal_ext(context, &princ,
-                                                       strlen(realm),
-                                                       realm,
-                                                       strlen(svcnames[j]),
-                                                       svcnames[j],
-                                                       strlen(myhostname),
-                                                       myhostname,
-                                                       NULL);
+                       char spn[300];
+
+                       /*
+                        * The special svcname "$" means 'try the active
+                        * directory machine account'
+                        */
+                       if (strcmp(svcnames[j],"$") == 0) {
+                               snprintf(spn, sizeof(spn), "%s@%s", myhostad, realm);
+                               code = krb5_build_principal_ext(context, &princ,
+                                                               strlen(realm),
+                                                               realm,
+                                                               strlen(myhostad),
+                                                               myhostad,
+                                                               NULL);
+                       } else {
+                               snprintf(spn, sizeof(spn), "%s/%s@%s",
+                                        svcnames[j], myhostname, realm);
+                               code = krb5_build_principal_ext(context, &princ,
+                                                               strlen(realm),
+                                                               realm,
+                                                               strlen(svcnames[j]),
+                                                               svcnames[j],
+                                                               strlen(myhostname),
+                                                               myhostname,
+                                                               NULL);
+                       }
+
                        if (code) {
                                k5err = gssd_k5_err_msg(context, code);
-                               printerr(1, "%s while building principal for "
-                                        "'%s/%s@%s'\n", k5err, svcnames[j],
-                                        myhostname, realm);
+                               printerr(1, "%s while building principal for '%s'\n",
+                                        k5err, spn);
                                continue;
                        }
                        code = krb5_kt_get_entry(context, kt, princ, 0, 0, kte);
                        krb5_free_principal(context, princ);
                        if (code) {
                                k5err = gssd_k5_err_msg(context, code);
-                               printerr(3, "%s while getting keytab entry for "
-                                        "'%s/%s@%s'\n", k5err, svcnames[j],
-                                        myhostname, realm);
+                               printerr(3, "%s while getting keytab entry for '%s'\n",
+                                        k5err, spn);
                        } else {
-                               printerr(3, "Success getting keytab entry for "
-                                        "'%s/%s@%s'\n",
-                                        svcnames[j], myhostname, realm);
+                               printerr(3, "Success getting keytab entry for '%s'\n",spn);
                                retval = 0;
                                goto out;
                        }
@@ -870,6 +894,8 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
                 */
                for (j = 0; svcnames[j] != NULL; j++) {
                        int found = 0;
+                       if (strcmp(svcnames[j],"$") == 0)
+                               continue;
                        code = gssd_search_krb5_keytab(context, kt, realm,
                                                       svcnames[j], &found, kte);
                        if (!code && found) {
@@ -1160,7 +1186,7 @@ gssd_refresh_krb5_machine_credential(char *hostname,
        krb5_keytab kt = NULL;;
        int retval = 0;
        char *k5err = NULL;
-       const char *svcnames[4] = { "root", "nfs", "host", NULL };
+       const char *svcnames[5] = { "$", "root", "nfs", "host", NULL };
 
        /*
         * If a specific service name was specified, use it.
index 9b463f3..1afff9e 100644 (file)
@@ -262,11 +262,19 @@ main(int argc, char *argv[])
                                "/etc/krb5.keytab?\n");
                        exit(1);
                }
+       } else {
+               status = gssd_acquire_cred(NULL,
+                       (const gss_OID)GSS_C_NT_HOSTBASED_SERVICE);
+               if (status == FALSE) {
+                       printerr(0, "unable to obtain nameless credentials\n");
+                       exit(1);
+               }
        }
 
        if (!fg)
                release_parent();
 
+       nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
        gssd_run();
        printerr(0, "gssd_run returned!\n");
        abort();
index 1c7bb32..7b2de6b 100644 (file)
@@ -6,7 +6,7 @@
 .SH NAME
 rpc.svcgssd \- server-side rpcsec_gss daemon
 .SH SYNOPSIS
-.B "rpc.svcgssd [-v] [-r] [-i] [-f] [-p principal]"
+.B "rpc.svcgssd [-n] [-v] [-r] [-i] [-f] [-p principal]"
 .SH DESCRIPTION
 The rpcsec_gss protocol gives a means of using the gss-api generic security
 api to provide security for protocols using rpc (in particular, nfs).  Before
@@ -37,7 +37,14 @@ If the nfsidmap library supports setting debug level,
 increases the verbosity of the output (can be specified multiple times).
 .TP
 .B -p
-Use \fIprincipal\fR instead of the default nfs/host.domain.
+Use \fIprincipal\fR instead of the default
+.RI nfs/ FQDN @ REALM .
+.TP
+.B -n
+Use the system default credentials
+.RI (host/ FQDN @ REALM )
+rather than the default
+.RI nfs/ FQDN @ REALM .
 .SH SEE ALSO
 .BR rpc.gssd(8),
 .SH AUTHORS
diff --git a/utils/gssd/svcgssd_krb5.c b/utils/gssd/svcgssd_krb5.c
new file mode 100644 (file)
index 0000000..fc67a6f
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * COPYRIGHT (c) 2011
+ * The Regents of the University of Michigan
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization.  If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <gssapi/gssapi.h>
+#include <krb5.h>
+
+#include "gss_util.h"
+#include "gss_oids.h"
+#include "err_util.h"
+#include "svcgssd_krb5.h"
+
+#define MYBUFLEN 1024
+
+char *supported_enctypes_filename = "/proc/fs/nfsd/supported_krb5_enctypes";
+int parsed_num_enctypes = 0;
+krb5_enctype *parsed_enctypes = NULL;
+char *cached_enctypes = NULL;
+
+/*==========================*/
+/*===  Internal routines ===*/
+/*==========================*/
+
+/*
+ * Parse the supported encryption type information
+ */
+static int
+parse_enctypes(char *enctypes)
+{
+       int n = 0;
+       char *curr, *comma;
+       int i;
+
+       /* Don't parse the same string over and over... */
+       if (cached_enctypes && strcmp(cached_enctypes, enctypes) == 0)
+               return 0;
+
+       /* Free any existing cached_enctypes */
+       free(cached_enctypes);
+
+       if (parsed_enctypes != NULL) {
+               free(parsed_enctypes);
+               parsed_enctypes = NULL;
+               parsed_num_enctypes = 0;
+       }
+
+       /* count the number of commas */
+       for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
+               comma = strchr(curr, ',');
+               if (comma != NULL)
+                       n++;
+               else
+                       break;
+       }
+
+       /* If no more commas and we're not at the end, there's one more value */
+       if (*curr != '\0')
+               n++;
+
+       /* Empty string, return an error */
+       if (n == 0)
+               return ENOENT;
+
+       /* Allocate space for enctypes array */
+       if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
+               return ENOMEM;
+       }
+
+       /* Now parse each value into the array */
+       for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
+               parsed_enctypes[i++] = atoi(curr);
+               comma = strchr(curr, ',');
+               if (comma == NULL)
+                       break;
+       }
+
+       parsed_num_enctypes = n;
+       if ((cached_enctypes = malloc(strlen(enctypes)+1)))
+               strcpy(cached_enctypes, enctypes);
+
+       return 0;
+}
+
+static void
+get_kernel_supported_enctypes(void)
+{
+       FILE *s_e;
+       int ret;
+       char buffer[MYBUFLEN + 1];
+
+       memset(buffer, '\0', sizeof(buffer));
+
+       s_e = fopen(supported_enctypes_filename, "r");
+       if (s_e == NULL)
+               goto out_clean_parsed;
+
+       ret = fread(buffer, 1, MYBUFLEN, s_e);
+       if (ret < 0) {
+               fclose(s_e);
+               goto out_clean_parsed;
+       }
+       fclose(s_e);
+       if (parse_enctypes(buffer)) {
+               goto out_clean_parsed;
+       }
+out:
+       return;
+
+out_clean_parsed:
+       if (parsed_enctypes != NULL) {
+               free(parsed_enctypes);
+               parsed_num_enctypes = 0;
+       }
+       goto out;
+}
+
+/*==========================*/
+/*===  External routines ===*/
+/*==========================*/
+
+/*
+ * Get encryption types supported by the kernel, and then
+ * call gss_krb5_set_allowable_enctypes() to limit the
+ * encryption types negotiated.
+ *
+ * Returns:
+ *     0 => all went well
+ *     -1 => there was an error
+ */
+
+int
+svcgssd_limit_krb5_enctypes(void)
+{
+#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
+       u_int maj_stat, min_stat;
+       krb5_enctype default_enctypes[] = { ENCTYPE_DES_CBC_CRC,
+                                           ENCTYPE_DES_CBC_MD5,
+                                           ENCTYPE_DES_CBC_MD4 };
+       int default_num_enctypes =
+               sizeof(default_enctypes) / sizeof(default_enctypes[0]);
+       krb5_enctype *enctypes;
+       int num_enctypes;
+
+       get_kernel_supported_enctypes();
+
+       if (parsed_enctypes != NULL) {
+               enctypes = parsed_enctypes;
+               num_enctypes = parsed_num_enctypes;
+       } else {
+               enctypes = default_enctypes;
+               num_enctypes = default_num_enctypes;
+       }
+
+       maj_stat = gss_set_allowable_enctypes(&min_stat, gssd_creds,
+                       &krb5oid, num_enctypes, enctypes);
+       if (maj_stat != GSS_S_COMPLETE) {
+               printerr(1, "WARNING: gss_set_allowable_enctypes failed\n");
+               pgsserr("svcgssd_limit_krb5_enctypes: gss_set_allowable_enctypes",
+                       maj_stat, min_stat, &krb5oid);
+               return -1;
+       }
+#endif
+       return 0;
+}
diff --git a/utils/gssd/svcgssd_krb5.h b/utils/gssd/svcgssd_krb5.h
new file mode 100644 (file)
index 0000000..07d5eb9
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * COPYRIGHT (c) 2011
+ * The Regents of the University of Michigan
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization.  If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#ifndef SVCGSSD_KRB5_H
+#define SVCGSSD_KRB5_H
+
+int svcgssd_limit_krb5_enctypes(void);
+
+#endif /* SVCGSSD_KRB5_H */
index 3894078..c714d99 100644 (file)
@@ -56,7 +56,9 @@
 #include "gss_util.h"
 #include "err_util.h"
 #include "context.h"
+#include "misc.h"
 #include "gss_oids.h"
+#include "svcgssd_krb5.h"
 
 extern char * mech2file(gss_OID mech);
 #define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel"
@@ -70,6 +72,7 @@ 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,
@@ -91,6 +94,7 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
                             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);
        /* XXX are types OK for the rest of this? */
        /* For context cache, use the actual context endtime */
@@ -241,7 +245,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred)
                        "file for name '%s'\n", sname);
                goto out_free;
        }
-       nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
+
        res = nfs4_gss_princ_to_ids(secname, sname, &uid, &gid);
        if (res < 0) {
                /*
@@ -443,6 +447,10 @@ handle_nullreq(FILE *f) {
                memcpy(&ctx, in_handle.value, in_handle.length);
        }
 
+       if (svcgssd_limit_krb5_enctypes()) {
+               goto out_err;
+       }
+
        maj_stat = gss_accept_sec_context(&min_stat, &ctx, gssd_creds,
                        &in_tok, GSS_C_NO_CHANNEL_BINDINGS, &client_name,
                        &mech, &out_tok, &ret_flags, NULL, NULL);
index 4218048..4328e41 100644 (file)
@@ -11,12 +11,8 @@ EXTRA_DIST = \
        idmapd.conf
 
 idmapd_SOURCES = \
-       atomicio.c \
        idmapd.c \
-       strlcat.c \
-       strlcpy.c \
        \
-       cfg.h \
        nfs_idmap.h \
        queue.h
 
diff --git a/utils/idmapd/atomicio.c b/utils/idmapd/atomicio.c
deleted file mode 100644 (file)
index 1fb1ff9..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2002 Marius Aamodt Eriksen <marius@monkey.org>
- * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
- * All rights reserved.
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-/*
- * ensure all of data on socket comes through. f==read || f==write
- */
-ssize_t
-atomicio(
-       ssize_t (*f) (int, void*, size_t),
-       int fd,
-       void *_s,
-       size_t n)
-{
-       char *s = _s;
-       ssize_t res;
-       size_t pos = 0;
-
-       while (n > pos) {
-               res = (f) (fd, s + pos, n - pos);
-               switch (res) {
-               case -1:
-                       if (errno == EINTR || errno == EAGAIN)
-                               continue;
-               case 0:
-                       if (pos != 0)
-                               return (pos);
-                       return (res);
-               default:
-                       pos += res;
-               }
-       }
-       return (pos);
-}
index b76607a..76a56ef 100644 (file)
@@ -158,10 +158,6 @@ static int nfsdopenone(struct idmap_client *);
 static void nfsdreopen_one(struct idmap_client *);
 static void nfsdreopen(void);
 
-size_t  strlcat(char *, const char *, size_t);
-size_t  strlcpy(char *, const char *, size_t);
-ssize_t atomicio(ssize_t (*f) (int, void*, size_t),
-                int, void *, size_t);
 void    mydaemon(int, int);
 void    release_parent(void);
 
diff --git a/utils/idmapd/strlcat.c b/utils/idmapd/strlcat.c
deleted file mode 100644 (file)
index daedd7a..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*     $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $     */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * 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. The name of the author may not 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 AUTHOR 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.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left).  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-strlcat(char *dst,
-       const char *src,
-       size_t siz)
-{
-       register char *d = dst;
-       register const char *s = src;
-       register size_t n = siz;
-       size_t dlen;
-
-       /* Find the end of dst and adjust bytes left but don't go past end */
-       while (n-- != 0 && *d != '\0')
-               d++;
-       dlen = d - dst;
-       n = siz - dlen;
-
-       if (n == 0)
-               return(dlen + strlen(s));
-       while (*s != '\0') {
-               if (n != 1) {
-                       *d++ = *s;
-                       n--;
-               }
-               s++;
-       }
-       *d = '\0';
-
-       return(dlen + (s - src));       /* count does not include NUL */
-}
diff --git a/utils/idmapd/strlcpy.c b/utils/idmapd/strlcpy.c
deleted file mode 100644 (file)
index a2653ee..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*     $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $     */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * 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. The name of the author may not 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 AUTHOR 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.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-/*
- * Copy src to string dst of size siz.  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t
-strlcpy(char *dst,
-       const char *src,
-       size_t siz)
-{
-       register char *d = dst;
-       register const char *s = src;
-       register size_t n = siz;
-
-       /* Copy as many bytes as will fit */
-       if (n != 0 && --n != 0) {
-               do {
-                       if ((*d++ = *s++) == 0)
-                               break;
-               } while (--n != 0);
-       }
-
-       /* Not enough room in dst, add NUL and traverse rest of src */
-       if (n == 0) {
-               if (siz != 0)
-                       *d = '\0';              /* NUL-terminate dst */
-               while (*s++)
-                       ;
-       }
-
-       return(s - src - 1);    /* count does not include NUL */
-}
index 299384a..7bc3e2b 100644 (file)
@@ -9,17 +9,16 @@ man5_MANS     = nfs.man
 
 sbin_PROGRAMS  = mount.nfs
 EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS)
-mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c \
+mount_common = error.c network.c token.c \
                    parse_opt.c parse_dev.c \
                    nfsmount.c nfs4mount.c stropts.c\
-                   nfsumount.c \
-                   mount_constants.h error.h network.h fstab.h token.h \
+                   mount_constants.h error.h network.h token.h \
                    parse_opt.h parse_dev.h \
                    nfs4_mount.h nfs_mount4.h stropts.h version.h \
-                       mount_config.h
+                   mount_config.h utils.c utils.h
 
 if MOUNT_CONFIG
-mount_nfs_SOURCES += configfile.c
+mount_common += configfile.c
 man5_MANS += nfsmount.conf.man
 EXTRA_DIST += nfsmount.conf
 endif
@@ -27,6 +26,16 @@ endif
 mount_nfs_LDADD = ../../support/nfs/libnfs.a \
                  ../../support/export/libexport.a
 
+mount_nfs_SOURCES = $(mount_common)
+
+if CONFIG_LIBMOUNT
+mount_nfs_SOURCES += mount_libmount.c
+mount_nfs_LDADD += $(LIBMOUNT)
+else
+mount_nfs_SOURCES += mount.c fstab.c nfsumount.c fstab.h
+
+endif
+
 MAINTAINERCLEANFILES = Makefile.in
 
 install-exec-hook:
index 051fa38..1fc9efe 100644 (file)
@@ -331,16 +331,43 @@ lock_mtab (void) {
                int sig = 0;
                struct sigaction sa;
 
-               sa.sa_handler = handler;
                sa.sa_flags = 0;
                sigfillset (&sa.sa_mask);
   
-               while (sigismember (&sa.sa_mask, ++sig) != -1
-                      && sig != SIGCHLD) {
-                       if (sig == SIGALRM)
+               while (sigismember (&sa.sa_mask, ++sig) != -1) {
+                       switch(sig) {
+                       case SIGCHLD:
+                       case SIGKILL:
+                       case SIGCONT:
+                       case SIGSTOP:
+                               /* The cannot be caught, or should not,
+                                * so don't even try.
+                                */
+                               continue;
+                       case SIGALRM:
                                sa.sa_handler = setlkw_timeout;
-                       else
+                               break;
+                       case SIGHUP:
+                       case SIGINT:
+                       case SIGQUIT:
+                       case SIGWINCH:
+                       case SIGTSTP:
+                       case SIGTTIN:
+                       case SIGTTOU:
+                       case SIGPIPE:
+                       case SIGXFSZ:
+                       case SIGXCPU:
+                               /* non-priv user can cause these to be
+                                * generated, so ignore them.
+                                */
+                               sa.sa_handler = SIG_IGN;
+                               break;
+                       default:
+                               /* The rest should not be possible, so just
+                                * print a message and unlock mtab.
+                                */
                                sa.sa_handler = handler;
+                       }
                        sigaction (sig, &sa, (struct sigaction *) 0);
                }
                signals_have_been_setup = 1;
@@ -364,19 +391,22 @@ lock_mtab (void) {
        /* Repeat until it was us who made the link */
        while (!we_created_lockfile) {
                struct flock flock;
-               int errsv, j;
+               int j;
 
                j = link(linktargetfile, MOUNTED_LOCK);
-               errsv = errno;
 
-               if (j == 0)
-                       we_created_lockfile = 1;
+               {
+                       int errsv = errno;
 
-               if (j < 0 && errsv != EEXIST) {
-                       (void) unlink(linktargetfile);
-                       die (EX_FILEIO, _("can't link lock file %s: %s "
-                            "(use -n flag to override)"),
-                            MOUNTED_LOCK, strerror (errsv));
+                       if (j == 0)
+                               we_created_lockfile = 1;
+
+                       if (j < 0 && errsv != EEXIST) {
+                               (void) unlink(linktargetfile);
+                               die (EX_FILEIO, _("can't link lock file %s: %s "
+                                    "(use -n flag to override)"),
+                                    MOUNTED_LOCK, strerror (errsv));
+                       }
                }
 
                lockfile_fd = open (MOUNTED_LOCK, O_WRONLY);
@@ -414,7 +444,7 @@ lock_mtab (void) {
                        }
                        (void) unlink(linktargetfile);
                } else {
-                       static int tries = 0;
+                       static int retries = 0;
 
                        /* Someone else made the link. Wait. */
                        alarm(LOCK_TIMEOUT);
@@ -428,10 +458,10 @@ lock_mtab (void) {
                        alarm(0);
                        /* Limit the number of iterations - maybe there
                           still is some old /etc/mtab~ */
-                       ++tries;
-                       if (tries % 200 == 0)
+                       ++retries;
+                       if (retries % 200 == 0)
                           usleep(30);
-                       if (tries > 100000) {
+                       if (retries > 100000) {
                                (void) unlink(linktargetfile);
                                close(lockfile_fd);
                                die (EX_FILEIO, _("Cannot create link %s\n"
index 82b9169..eea00af 100644 (file)
@@ -47,7 +47,7 @@
 #include "mount.h"
 #include "error.h"
 #include "stropts.h"
-#include "version.h"
+#include "utils.h"
 
 char *progname;
 int nfs_mount_data_version;
@@ -150,49 +150,6 @@ static const struct opt_map opt_map[] = {
 static void parse_opts(const char *options, int *flags, char **extra_opts);
 
 /*
- * Choose the version of the nfs_mount_data structure that is appropriate
- * for the kernel that is doing the mount.
- *
- * NFS_MOUNT_VERSION:          maximum version supported by these sources
- * nfs_mount_data_version:     maximum version supported by the running kernel
- */
-static void discover_nfs_mount_data_version(void)
-{
-       unsigned int kernel_version = linux_version_code();
-
-       if (kernel_version) {
-               if (kernel_version < MAKE_VERSION(2, 1, 32))
-                       nfs_mount_data_version = 1;
-               else if (kernel_version < MAKE_VERSION(2, 2, 18))
-                       nfs_mount_data_version = 3;
-               else if (kernel_version < MAKE_VERSION(2, 3, 0))
-                       nfs_mount_data_version = 4;
-               else if (kernel_version < MAKE_VERSION(2, 3, 99))
-                       nfs_mount_data_version = 3;
-               else if (kernel_version < MAKE_VERSION(2, 6, 3))
-                       nfs_mount_data_version = 4;
-               else
-                       nfs_mount_data_version = 6;
-       }
-       if (nfs_mount_data_version > NFS_MOUNT_VERSION)
-               nfs_mount_data_version = NFS_MOUNT_VERSION;
-       else
-               if (kernel_version > MAKE_VERSION(2, 6, 22))
-                       string++;
-}
-
-static void print_one(char *spec, char *node, char *type, char *opts)
-{
-       if (!verbose)
-               return;
-
-       if (opts)
-               printf(_("%s on %s type %s (%s)\n"), spec, node, type, opts);
-       else
-               printf(_("%s on %s type %s\n"), spec, node, type);
-}
-
-/*
  * Build a canonical mount option string for /etc/mtab.
  */
 static char *fix_opts_string(int flags, const char *extra_opts)
@@ -209,7 +166,7 @@ static char *fix_opts_string(int flags, const char *extra_opts)
        }
        if (flags & MS_USERS)
                new_opts = xstrconcat3(new_opts, ",users", "");
-       
+
        for (om = opt_map; om->opt != NULL; om++) {
                if (om->skip)
                        continue;
@@ -224,6 +181,20 @@ static char *fix_opts_string(int flags, const char *extra_opts)
        return new_opts;
 }
 
+static void
+init_mntent(struct mntent *mnt, char *fsname, char *dir, char *type,
+               int flags, char *opts)
+{
+       mnt->mnt_fsname = fsname;
+       mnt->mnt_dir    = dir;
+       mnt->mnt_type   = type;
+       mnt->mnt_opts   = fix_opts_string(flags & ~MS_NOMTAB, opts);
+
+       /* these are always zero for NFS */
+       mnt->mnt_freq   = 0;
+       mnt->mnt_passno = 0;
+}
+
 /* Create mtab with a root entry.  */
 static void
 create_mtab (void) {
@@ -245,11 +216,8 @@ create_mtab (void) {
        if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
                char *extra_opts;
                parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
-               mnt.mnt_dir = "/";
-               mnt.mnt_fsname = xstrdup(fstab->m.mnt_fsname);
-               mnt.mnt_type = fstab->m.mnt_type;
-               mnt.mnt_opts = fix_opts_string (flags, extra_opts);
-               mnt.mnt_freq = mnt.mnt_passno = 0;
+               init_mntent(&mnt, xstrdup(fstab->m.mnt_fsname), "/",
+                               fstab->m.mnt_type, flags, extra_opts);
                free(extra_opts);
 
                if (nfs_addmntent (mfp, &mnt) == 1) {
@@ -273,17 +241,12 @@ create_mtab (void) {
 }
 
 static int add_mtab(char *spec, char *mount_point, char *fstype,
-                       int flags, char *opts, int freq, int pass)
+                       int flags, char *opts)
 {
        struct mntent ment;
        int result = EX_SUCCESS;
 
-       ment.mnt_fsname = spec;
-       ment.mnt_dir = mount_point;
-       ment.mnt_type = fstype;
-       ment.mnt_opts = fix_opts_string(flags, opts);
-       ment.mnt_freq = freq;
-       ment.mnt_passno = pass;
+       init_mntent(&ment, spec, mount_point, fstype, flags, opts);
 
        if (!nomtab && mtab_does_not_exist()) {
                if (verbose > 1)
@@ -321,23 +284,7 @@ static int add_mtab(char *spec, char *mount_point, char *fstype,
        return result;
 }
 
-void mount_usage(void)
-{
-       printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"),
-               progname);
-       printf(_("options:\n"));
-       printf(_("\t-r\t\tMount file system readonly\n"));
-       printf(_("\t-v\t\tVerbose\n"));
-       printf(_("\t-V\t\tPrint version\n"));
-       printf(_("\t-w\t\tMount file system read-write\n"));
-       printf(_("\t-f\t\tFake mount, do not actually mount\n"));
-       printf(_("\t-n\t\tDo not update /etc/mtab\n"));
-       printf(_("\t-s\t\tTolerate sloppy mount options rather than fail\n"));
-       printf(_("\t-h\t\tPrint this help\n"));
-       printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n"));
-}
-
-static void parse_opt(const char *opt, int *mask, char *extra_opts, int len)
+static void parse_opt(const char *opt, int *mask, char *extra_opts, size_t len)
 {
        const struct opt_map *om;
 
@@ -371,7 +318,7 @@ static void parse_opts(const char *options, int *flags, char **extra_opts)
        if (options != NULL) {
                char *opts = xstrdup(options);
                char *opt, *p;
-               int len = strlen(opts) + 1;     /* include room for a null */
+               size_t len = strlen(opts) + 1;  /* include room for a null */
                int open_quote = 0;
 
                *extra_opts = xmalloc(len);
@@ -397,26 +344,6 @@ static void parse_opts(const char *options, int *flags, char **extra_opts)
        }
 }
 
-static int chk_mountpoint(char *mount_point)
-{
-       struct stat sb;
-
-       if (stat(mount_point, &sb) < 0){
-               mount_error(NULL, mount_point, errno);
-               return 1;
-       }
-       if (S_ISDIR(sb.st_mode) == 0){
-               mount_error(NULL, mount_point, ENOTDIR);
-               return 1;
-       }
-       if (access(mount_point, X_OK) < 0) {
-               mount_error(NULL, mount_point, errno);
-               return 1;
-       }
-
-       return 0;
-}
-
 static int try_mount(char *spec, char *mount_point, int flags,
                        char *fs_type, char **extra_opts, char *mount_opts,
                        int fake, int bg)
@@ -441,45 +368,31 @@ static int try_mount(char *spec, char *mount_point, int flags,
        if (!fake)
                print_one(spec, mount_point, fs_type, mount_opts);
 
-       ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts,
-                       0, 0 /* these are always zero for NFS */ );
-       return ret;
+       return add_mtab(spec, mount_point, fs_type, flags, *extra_opts);
 }
 
 int main(int argc, char *argv[])
 {
        int c, flags = 0, mnt_err = 1, fake = 0;
-       char *spec, *mount_point, *fs_type = "nfs";
+       char *spec = NULL, *mount_point = NULL, *fs_type = "nfs";
        char *extra_opts = NULL, *mount_opts = NULL;
        uid_t uid = getuid();
 
        progname = basename(argv[0]);
 
-       discover_nfs_mount_data_version();
+       nfs_mount_data_version = discover_nfs_mount_data_version(&string);
 
        if(!strncmp(progname, "umount", strlen("umount")))
                exit(nfsumount(argc, argv));
 
-       if (argv[1] && argv[1][0] == '-') {
-               if(argv[1][1] == 'V')
-                       printf("%s ("PACKAGE_STRING")\n", progname);
-               else
-                       mount_usage();
-               exit(EX_SUCCESS);
-       }
-
        if ((argc < 3)) {
                mount_usage();
                exit(EX_USAGE);
        }
 
-       spec = argv[1];
-       mount_point = argv[2];
-
        mount_config_init(progname);
 
-       argv[2] = argv[0]; /* so that getopt error messages are correct */
-       while ((c = getopt_long(argc - 2, argv + 2, "rvVwfno:hs",
+       while ((c = getopt_long(argc, argv, "rvVwfno:hs",
                                longopts, NULL)) != -1) {
                switch (c) {
                case 'r':
@@ -522,6 +435,14 @@ int main(int argc, char *argv[])
        if (optind != argc - 2) {
                mount_usage();
                goto out_usage;
+       } else {
+               while (optind < argc) {
+                       if (!spec)
+                               spec = argv[optind];
+                       else
+                               mount_point = argv[optind];
+                       optind++;
+               }
        }
 
        if (strcmp(progname, "mount.nfs4") == 0)
index 3023306..69ffd1e 100644 (file)
@@ -1,7 +1,7 @@
-#ifndef _LINUX_MOUNT__CONFIG_H
-#define _LINUX_MOUNT_CONFIG__H
+#ifndef _LINUX_MOUNT_CONFIG_H
+#define _LINUX_MOUNT_CONFIG_H
 /*
- * mount_config.h -- mount configuration file routines 
+ * mount_config.h -- mount configuration file routines
  * Copyright (C) 2008 Red Hat, Inc <nfs@redhat.com>
  *
  * This program is free software; you can redistribute it and/or modify
  *
  */
 
-inline void mount_config_init(char *);
-
 #ifdef MOUNT_CONFIG
 #include "conffile.h"
 #include "xlog.h"
 
 extern char *conf_get_mntopts(char *, char *, char *);
 
-inline void mount_config_init(char *program)
+static inline void mount_config_init(char *program)
 {
        xlog_open(program);
        /*
@@ -32,19 +30,22 @@ inline void mount_config_init(char *program)
         */
        conf_init();
 }
-inline char *mount_config_opts(char *spec, 
+
+static inline char *mount_config_opts(char *spec,
                char *mount_point, char *mount_opts)
 {
        return conf_get_mntopts(spec, mount_point, mount_opts);
 }
+
 #else /* MOUNT_CONFIG */
 
-inline void mount_config_init(char *program) { }
+static inline void mount_config_init(__attribute__ ((unused)) char *program) { }
 
-inline char *mount_config_opts(char *spec, 
-               char *mount_point, char *mount_opts)
+static inline char *mount_config_opts(__attribute__ ((unused)) char *spec,
+               __attribute__ ((unused)) char *mount_point, char *mount_opts)
 {
        return mount_opts;
 }
 #endif /* MOUNT_CONFIG */
-#endif
+
+#endif /* _LINUX_MOUNT_CONFIG_H */
index cbfb099..4d050d8 100644 (file)
@@ -64,4 +64,8 @@ if we have a stack or plain mount - mount atop of it, forming a stack. */
 #define MS_MGC_MSK 0xffff0000  /* magic flag number mask */
 #endif
 
+/* Generic options that are prevented from appearing
+ * in the options field in /etc/mtab. */
+#define MS_NOMTAB      (MS_REMOUNT)
+
 #endif /* _NFS_UTILS_MOUNT_CONSTANTS_H */
diff --git a/utils/mount/mount_libmount.c b/utils/mount/mount_libmount.c
new file mode 100644 (file)
index 0000000..6dd6484
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * mount_libmount.c -- Linux NFS [u]mount based on libmount
+ *
+ * Copyright (C) 2011 Karel Zak <kzak@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include <libmount/libmount.h>
+
+#include "nls.h"
+#include "mount_config.h"
+
+#include "nfs_mount.h"
+#include "nfs4_mount.h"
+#include "stropts.h"
+#include "version.h"
+#include "xcommon.h"
+
+#include "error.h"
+#include "utils.h"
+
+char *progname;
+int nfs_mount_data_version;
+int verbose;
+int sloppy;
+int string;
+int nomtab;
+
+#define FOREGROUND     (0)
+#define BACKGROUND     (1)
+
+/*
+ * Store mount options to mtab (or /dev/.mount/utab), called from mount.nfs.
+ *
+ * Note that on systems without /etc/mtab the fs-specific options are not
+ * managed by libmount at all. We have to use "mount attributes" that are
+ * private for mount.<type> helpers.
+ */
+static void store_mount_options(struct libmnt_fs *fs, const char *opts)
+{
+       mnt_fs_set_fs_options(fs, opts);        /* for mtab */
+       mnt_fs_set_attributes(fs, opts);        /* for non-mtab systems */
+}
+
+/*
+ * Retrieve mount options from mtab (or /dev/.mount/utab) called from umount.nfs.
+ *
+ * The result can passed to free().
+ */
+char *retrieve_mount_options(struct libmnt_fs *fs)
+{
+       const char *opts;
+
+       if (!fs)
+               return NULL;
+
+       opts = mnt_fs_get_attributes(fs);       /* /dev/.mount/utab */
+       if (opts)
+               return strdup(opts);
+
+       return mnt_fs_strdup_options(fs);       /* /etc/mtab */
+}
+
+static int try_mount(struct libmnt_context *cxt, int bg)
+{
+       struct libmnt_fs *fs;
+       const char *p;
+       char *src = NULL, *tgt = NULL, *type = NULL, *opts = NULL;
+       unsigned long flags = 0;
+       int fake, ret = 0;
+
+       fs = mnt_context_get_fs(cxt);
+
+       /* libmount returns read-only pointers (const char)
+        * so, reallocate for nfsmount() functions.
+        */
+       if ((p = mnt_fs_get_source(fs)))        /* spec */
+               src = strdup(p);
+       if ((p = mnt_fs_get_target(fs)))        /* mountpoint */
+               tgt = strdup(p);
+       if ((p = mnt_fs_get_fstype(fs)))        /* FS type */
+               type = strdup(p);
+       if ((p = mnt_fs_get_fs_options(fs)))    /* mount options */
+               opts = strdup(p);
+
+       mnt_context_get_mflags(cxt, &flags);    /* mount(2) flags */
+       fake = mnt_context_is_fake(cxt);
+
+       if (string)
+               ret = nfsmount_string(src, tgt, type, flags, &opts, fake, bg);
+
+       else if (strcmp(type, "nfs4") == 0)
+               ret = nfs4mount(src, tgt, flags, &opts, fake, bg);
+       else
+               ret = nfsmount(src, tgt, flags, &opts, fake, bg);
+
+       /* Store mount options if not called with mount --no-mtab */
+       if (!ret && !mnt_context_is_nomtab(cxt))
+               store_mount_options(fs, opts);
+
+       free(src);
+       free(tgt);
+       free(type);
+       free(opts);
+
+       return ret;
+}
+
+/* returns: error = -1, success = 0 , unknown = 1 */
+static int is_vers4(struct libmnt_context *cxt)
+{
+       struct libmnt_fs *fs = mnt_context_get_fs(cxt);
+       struct libmnt_table *tb = NULL;
+       const char *src = mnt_context_get_source(cxt),
+                  *tgt = mnt_context_get_target(cxt);
+       int rc = 1;
+
+       if (!src || !tgt)
+               return -1;
+
+       if (!mnt_fs_is_kernel(fs)) {
+               struct libmnt_table *tb = mnt_new_table_from_file("/proc/mounts");
+
+               if (!tb)
+                       return -1;
+               fs = mnt_table_find_pair(tb, src, tgt, MNT_ITER_BACKWARD);
+       }
+
+       if (fs) {
+               const char *type = mnt_fs_get_fstype(fs);
+               if (type && strcmp(type, "nfs4") == 0)
+                       rc = 0;
+       }
+       mnt_free_table(tb);
+       return rc;
+}
+
+static int umount_main(struct libmnt_context *cxt, int argc, char **argv)
+{
+       int rc, c;
+       char *spec = NULL, *opts = NULL;
+
+       static const struct option longopts[] = {
+               { "force", 0, 0, 'f' },
+               { "help", 0, 0, 'h' },
+               { "no-mtab", 0, 0, 'n' },
+               { "verbose", 0, 0, 'v' },
+               { "read-only", 0, 0, 'r' },
+               { "lazy", 0, 0, 'l' },
+               { "types", 1, 0, 't' },
+               { NULL, 0, 0, 0 }
+       };
+
+       mnt_context_init_helper(cxt, MNT_ACT_UMOUNT, 0);
+
+       while ((c = getopt_long (argc, argv, "fvnrlh", longopts, NULL)) != -1) {
+
+               rc = mnt_context_helper_setopt(cxt, c, optarg);
+               if (rc == 0)            /* valid option */
+                       continue;
+               if (rc < 0)             /* error (probably ENOMEM) */
+                       goto err;
+                                       /* rc==1 means unknow option */
+               umount_usage();
+               return EX_USAGE;
+       }
+
+       if (optind < argc)
+               spec = argv[optind++];
+
+       if (!spec || (*spec != '/' && strchr(spec,':') == NULL)) {
+               nfs_error(_("%s: no mount point provided"), progname);
+               return EX_USAGE;
+       }
+
+       if (mnt_context_set_target(cxt, spec))
+               goto err;
+       if (mnt_context_set_fstype_pattern(cxt, "nfs,nfs4"))    /* restrict filesystems */
+               goto err;
+
+       /* read mtab/fstab, evaluate permissions, etc. */
+       rc = mnt_context_prepare_umount(cxt);
+       if (rc) {
+               nfs_error(_("%s: failed to prepare umount: %s\n"),
+                                       progname, strerror(-rc));
+               goto err;
+       }
+
+       opts = retrieve_mount_options(mnt_context_get_fs(cxt));
+
+       if (!mnt_context_is_lazy(cxt)) {
+               if (opts) {
+                       /* we have full FS description (e.g. from mtab or /proc) */
+                       switch (is_vers4(cxt)) {
+                       case 0:
+                               /* We ignore the error from nfs_umount23.
+                                * If the actual umount succeeds (in del_mtab),
+                                * we don't want to signal an error, as that
+                                * could cause /sbin/mount to retry!
+                                */
+                               nfs_umount23(mnt_context_get_source(cxt), opts);
+                               break;
+                       case 1:                 /* unknown */
+                               break;
+                       default:                /* error */
+                               goto err;
+                       }
+               } else
+                       /* strange, no entry in mtab or /proc not mounted */
+                       nfs_umount23(spec, "tcp,v3");
+       }
+
+       rc = mnt_context_do_umount(cxt);        /* call umount(2) syscall */
+       mnt_context_finalize_mount(cxt);        /* mtab update */
+
+       if (rc && !mnt_context_get_status(cxt)) {
+               /* mnt_context_do_umount() returns errno if umount(2) failed */
+               umount_error(rc, spec);
+               goto err;
+       }
+
+       free(opts);
+       return EX_SUCCESS;
+err:
+       free(opts);
+       return EX_FAIL;
+}
+
+static int mount_main(struct libmnt_context *cxt, int argc, char **argv)
+{
+       int rc, c;
+       struct libmnt_fs *fs;
+       char *spec = NULL, *mount_point = NULL, *opts = NULL;
+
+       static const struct option longopts[] = {
+         { "fake", 0, 0, 'f' },
+         { "help", 0, 0, 'h' },
+         { "no-mtab", 0, 0, 'n' },
+         { "read-only", 0, 0, 'r' },
+         { "ro", 0, 0, 'r' },
+         { "verbose", 0, 0, 'v' },
+         { "version", 0, 0, 'V' },
+         { "read-write", 0, 0, 'w' },
+         { "rw", 0, 0, 'w' },
+         { "options", 1, 0, 'o' },
+         { "sloppy", 0, 0, 's' },
+         { NULL, 0, 0, 0 }
+       };
+
+       mount_config_init(progname);
+       mnt_context_init_helper(cxt, MNT_ACT_MOUNT, 0);
+
+       while ((c = getopt_long(argc, argv, "fhnrVvwo:s", longopts, NULL)) != -1) {
+
+               rc = mnt_context_helper_setopt(cxt, c, optarg);
+               if (rc == 0)            /* valid option */
+                       continue;
+               if (rc < 0)             /* error (probably ENOMEM) */
+                       goto err;
+                                       /* rc==1 means unknow option */
+               switch (c) {
+               case 'V':
+                       printf("%s: ("PACKAGE_STRING")\n", progname);
+                       return EX_SUCCESS;
+               case 'h':
+               default:
+                       mount_usage();
+                       return EX_USAGE;
+               }
+       }
+
+       if (optind < argc)
+               spec = argv[optind++];
+       if (optind < argc)
+               mount_point = argv[optind++];
+
+       if (!mount_point) {
+               nfs_error(_("%s: no mount point provided"), progname);
+               goto err;
+       }
+       if (!spec) {
+               nfs_error(_("%s: no mount spec provided"), progname);
+               goto err;
+       }
+
+       if (geteuid() != 0) {
+               nfs_error(_("%s: not installed setuid - "
+                           "\"user\" NFS mounts not supported."), progname);
+               goto err;
+       }
+
+       verbose = mnt_context_is_verbose(cxt);
+       sloppy = mnt_context_is_sloppy(cxt);
+       nomtab = mnt_context_is_nomtab(cxt);
+
+       if (strcmp(progname, "mount.nfs4") == 0)
+               mnt_context_set_fstype(cxt, "nfs4");
+       else
+               mnt_context_set_fstype(cxt, "nfs");     /* default */
+
+       rc = mnt_context_set_source(cxt, spec);
+       if (!rc)
+               mnt_context_set_target(cxt, mount_point);
+       if (rc) {
+               nfs_error(_("%s: failed to set spec or mountpoint: %s"),
+                               progname, strerror(errno));
+               goto err;
+       }
+
+       mount_point = mnt_resolve_path(mount_point,
+                                      mnt_context_get_cache(cxt));
+
+       if (chk_mountpoint(mount_point))
+               goto err;
+       /*
+        * Concatenate mount options from the configuration file
+        */
+       fs = mnt_context_get_fs(cxt);
+       if (fs) {
+               opts = mnt_fs_strdup_options(fs);
+
+               opts = mount_config_opts(spec, mount_point, opts);
+               mnt_fs_set_options(fs, opts);
+       }
+
+       rc = mnt_context_prepare_mount(cxt);
+       if (rc) {
+               nfs_error(_("%s: failed to prepare mount: %s\n"),
+                                       progname, strerror(-rc));
+               goto err;
+       }
+
+       rc = try_mount(cxt, FOREGROUND);
+
+       if (rc == EX_BG) {
+               printf(_("%s: backgrounding \"%s\"\n"),
+                       progname, mnt_context_get_source(cxt));
+               printf(_("%s: mount options: \"%s\"\n"),
+                       progname, opts);
+
+               fflush(stdout);
+
+               if (daemon(0, 0)) {
+                       nfs_error(_("%s: failed to start "
+                                       "background process: %s\n"),
+                                       progname, strerror(errno));
+                       exit(EX_FAIL);
+               }
+
+               rc = try_mount(cxt, BACKGROUND);
+
+               if (verbose && rc)
+                       printf(_("%s: giving up \"%s\"\n"),
+                               progname, mnt_context_get_source(cxt));
+       }
+
+       mnt_context_set_syscall_status(cxt, rc == EX_SUCCESS ? 0 : -1);
+       mnt_context_finalize_mount(cxt);        /* mtab update */
+       return rc;
+err:
+       return EX_FAIL;
+}
+
+int main(int argc, char *argv[])
+{
+       struct libmnt_context *cxt;
+       int rc;
+
+       mnt_init_debug(0);
+       cxt = mnt_new_context();
+       if (!cxt) {
+               nfs_error(_("Can't initilize libmount: %s"),
+                                       strerror(errno));
+               rc = EX_FAIL;
+               goto done;
+       }
+
+       progname = basename(argv[0]);
+       nfs_mount_data_version = discover_nfs_mount_data_version(&string);
+
+       if(strncmp(progname, "umount", 6) == 0)
+               rc = umount_main(cxt, argc, argv);
+       else
+               rc = mount_main(cxt, argc, argv);
+done:
+       mnt_free_context(cxt);
+       return rc;
+}
index d612427..d1f91dc 100644 (file)
@@ -59,6 +59,8 @@
 #define CONNECT_TIMEOUT        (20)
 #define MOUNT_TIMEOUT  (30)
 
+#define SAFE_SOCKADDR(x)       (struct sockaddr *)(char *)(x)
+
 extern int nfs_mount_data_version;
 extern char *progname;
 extern int verbose;
@@ -208,9 +210,6 @@ int nfs_lookup(const char *hostname, const sa_family_t family,
 {
        struct addrinfo *gai_results;
        struct addrinfo gai_hint = {
-#ifdef HAVE_DECL_AI_ADDRCONFIG
-               .ai_flags       = AI_ADDRCONFIG,
-#endif /* HAVE_DECL_AI_ADDRCONFIG */
                .ai_family      = family,
        };
        socklen_t len = *salen;
@@ -428,12 +427,12 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
                if (bindresvport(so, &laddr) < 0)
                        goto err_bindresvport;
        } else {
-               cc = bind(so, (struct sockaddr *)&laddr, namelen);
+               cc = bind(so, SAFE_SOCKADDR(&laddr), namelen);
                if (cc < 0)
                        goto err_bind;
        }
        if (type == SOCK_STREAM || (conn && type == SOCK_DGRAM)) {
-               cc = connect_to(so, (struct sockaddr *)saddr, namelen,
+               cc = connect_to(so, SAFE_SOCKADDR(saddr), namelen,
                                timeout);
                if (cc < 0)
                        goto err_connect;
@@ -756,11 +755,12 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
  */
 int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
 {
-       return nfs_probe_bothports((struct sockaddr *)&mnt_server->saddr,
-                                       sizeof(mnt_server->saddr),
+       struct sockaddr *mnt_addr = SAFE_SOCKADDR(&mnt_server->saddr);
+       struct sockaddr *nfs_addr = SAFE_SOCKADDR(&nfs_server->saddr);
+
+       return nfs_probe_bothports(mnt_addr, sizeof(mnt_server->saddr),
                                        &mnt_server->pmap,
-                                       (struct sockaddr *)&nfs_server->saddr,
-                                       sizeof(nfs_server->saddr),
+                                       nfs_addr, sizeof(nfs_server->saddr),
                                        &nfs_server->pmap);
 }
 
@@ -772,7 +772,7 @@ static int nfs_probe_statd(void)
        };
        rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
 
-       return nfs_getport_ping((struct sockaddr *)&addr, sizeof(addr),
+       return nfs_getport_ping(SAFE_SOCKADDR(&addr), sizeof(addr),
                                program, (rpcvers_t)1, IPPROTO_UDP);
 }
 
@@ -901,7 +901,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
  */
 int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
 {
-       struct sockaddr *sap = (struct sockaddr *)&mnt_server->saddr;
+       struct sockaddr *sap = SAFE_SOCKADDR(&mnt_server->saddr);
        socklen_t salen = sizeof(mnt_server->saddr);
        struct pmap *pmap = &mnt_server->pmap;
        CLIENT *clnt;
@@ -1011,11 +1011,11 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
                struct sockaddr_in *caddr)
 {
        CLIENT *clnt = NULL;
-       int sock, stat;
+       int sock, status;
        static char clnt_res;
        struct sockaddr dissolve;
 
-       rpc_createerr.cf_stat = stat = 0;
+       rpc_createerr.cf_stat = status = 0;
        sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
        if (sock == RPC_ANYSOCK) {
                if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
@@ -1058,18 +1058,18 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
                return 0;
        }
        memset(&clnt_res, 0, sizeof(clnt_res));
-       stat = clnt_call(clnt, NULLPROC,
+       status = clnt_call(clnt, NULLPROC,
                         (xdrproc_t)xdr_void, (caddr_t)NULL,
                         (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
                         TIMEOUT);
-       if (stat) {
+       if (status) {
                clnt_geterr(clnt, &rpc_createerr.cf_error);
-               rpc_createerr.cf_stat = stat;
+               rpc_createerr.cf_stat = status;
        }
        clnt_destroy(clnt);
        close(sock);
 
-       if (stat == RPC_SUCCESS)
+       if (status == RPC_SUCCESS)
                return 1;
        else
                return 0;
@@ -1095,7 +1095,7 @@ static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
                .sin6_family            = AF_INET6,
                .sin6_addr              = IN6ADDR_ANY_INIT,
        };
-       int sock;
+       int sock, result = 0;
 
        sock = socket(sap->sa_family, SOCK_DGRAM, IPPROTO_UDP);
        if (sock < 0)
@@ -1103,28 +1103,26 @@ static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
 
        switch (sap->sa_family) {
        case AF_INET:
-               if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
-                       close(sock);
-                       return 0;
-               }
+               if (bind(sock, SAFE_SOCKADDR(&sin), sizeof(sin)) < 0)
+                       goto out;
                break;
        case AF_INET6:
-               if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
-                       close(sock);
-                       return 0;
-               }
+               if (bind(sock, SAFE_SOCKADDR(&sin6), sizeof(sin6)) < 0)
+                       goto out;
                break;
        default:
                errno = EAFNOSUPPORT;
-               return 0;
+               goto out;
        }
 
-       if (connect(sock, sap, salen) < 0) {
-               close(sock);
-               return 0;
-       }
+       if (connect(sock, sap, salen) < 0)
+               goto out;
 
-       return !getsockname(sock, buf, buflen);
+       result = !getsockname(sock, buf, buflen);
+
+out:
+       close(sock);
+       return result;
 }
 
 /*
@@ -1346,7 +1344,7 @@ nfs_nfs_port(struct mount_options *options, unsigned long *port)
        case PO_NOT_FOUND:
                break;
        case PO_FOUND:
-               if (tmp >= 1 && tmp <= 65535) {
+               if (tmp >= 0 && tmp <= 65535) {
                        *port = tmp;
                        return 1;
                }
@@ -1518,7 +1516,11 @@ nfs_mount_protocol(struct mount_options *options, unsigned long *protocol)
         * set @protocol to zero.  The pmap protocol value will
         * be filled in later by an rpcbind query in this case.
         */
-       return nfs_nfs_protocol(options, protocol);
+       if (!nfs_nfs_protocol(options, protocol))
+               return 0;
+       if (*protocol == NFSPROTO_RDMA)
+               *protocol = IPPROTO_TCP;
+       return 1;
 }
 
 /*
@@ -1534,7 +1536,7 @@ nfs_mount_port(struct mount_options *options, unsigned long *port)
        case PO_NOT_FOUND:
                break;
        case PO_FOUND:
-               if (tmp >= 1 && tmp <= 65535) {
+               if (tmp >= 0 && tmp <= 65535) {
                        *port = tmp;
                        return 1;
                }
@@ -1622,3 +1624,71 @@ int nfs_options2pmap(struct mount_options *options,
 
        return 1;
 }
+
+/*
+ * Discover mount server's hostname/address by examining mount options
+ *
+ * Returns a pointer to a string that the caller must free, on
+ * success; otherwise NULL is returned.
+ */
+static char *nfs_umount_hostname(struct mount_options *options,
+                                char *hostname)
+{
+       char *option;
+
+       option = po_get(options, "mountaddr");
+       if (option)
+               goto out;
+       option = po_get(options, "mounthost");
+       if (option)
+               goto out;
+       option = po_get(options, "addr");
+       if (option)
+               goto out;
+
+       return hostname;
+
+out:
+       free(hostname);
+       return strdup(option);
+}
+
+
+/*
+ * Returns EX_SUCCESS if mount options and device name have been
+ * parsed successfully; otherwise EX_FAIL.
+ */
+int nfs_umount_do_umnt(struct mount_options *options,
+                      char **hostname, char **dirname)
+{
+       union nfs_sockaddr address;
+       struct sockaddr *sap = &address.sa;
+       socklen_t salen = sizeof(address);
+       struct pmap nfs_pmap, mnt_pmap;
+       sa_family_t family;
+
+       if (!nfs_options2pmap(options, &nfs_pmap, &mnt_pmap))
+               return EX_FAIL;
+
+       /* Skip UMNT call for vers=4 mounts */
+       if (nfs_pmap.pm_vers == 4)
+               return EX_SUCCESS;
+
+       *hostname = nfs_umount_hostname(options, *hostname);
+       if (!*hostname) {
+               nfs_error(_("%s: out of memory"), progname);
+               return EX_FAIL;
+       }
+
+       if (!nfs_mount_proto_family(options, &family))
+               return 0;
+       if (!nfs_lookup(*hostname, family, sap, &salen))
+               /* nfs_lookup reports any errors */
+               return EX_FAIL;
+
+       if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) == 0)
+               /* nfs_advise_umount reports any errors */
+               return EX_FAIL;
+
+       return EX_SUCCESS;
+}
index 2a3a110..81c6f22 100644 (file)
@@ -75,4 +75,7 @@ int nfs_advise_umount(const struct sockaddr *, const socklen_t,
 CLIENT *mnt_openclnt(clnt_addr_t *, int *);
 void mnt_closeclnt(CLIENT *, int);
 
+int nfs_umount_do_umnt(struct mount_options *options,
+                      char **hostname, char **dirname);
+
 #endif /* _NFS_UTILS_MOUNT_NETWORK_H */
index 55d4b55..be91a25 100644 (file)
@@ -69,10 +69,9 @@ for details on specifying raw IPv6 addresses.
 .P
 The
 .I fstype
-field contains "nfs", for whatever version of the protocol.
-The
-.B nfs
-allow several mount options, which are described below.
+field contains "nfs".  Use of the "nfs4" fstype in
+.I /etc/fstab
+is deprecated.
 .SH "MOUNT OPTIONS"
 Refer to
 .BR mount (8)
@@ -464,9 +463,9 @@ by other clients, but can impact application and server performance.
 .IP
 The DATA AND METADATA COHERENCE section contains a
 detailed discussion of these trade-offs.
-.SS "Options for versions 2 and 3 only"
+.SS "Options for NFS versions 2 and 3 only"
 Use these options, along with the options in the above subsection,
-for NFSv2/v3 only. They will be ignored for newer versions.
+for NFS versions 2 and 3 only.
 .TP 1.5i
 .BI proto= netid
 The transport protocol name and protocol family the NFS client uses
@@ -619,7 +618,7 @@ in such cases.
 .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 negociate a suitable version with
+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
@@ -717,9 +716,53 @@ If this option is not specified, the NFS client uses READDIRPLUS requests
 on NFS version 3 mounts to read small directories.
 Some applications perform better if the client uses only READDIR requests
 for all directories.
-.SS "Options for version 4 only"
+.TP 1.5i
+.BR local_lock= mechanism
+Specifies whether to use local locking for any or both of the flock and the
+POSIX locking mechanisms.
+.I mechanism
+can be one of
+.BR all ,
+.BR flock ,
+.BR posix ,
+or
+.BR none .
+This option is supported in kernels 2.6.37 and later.
+.IP
+The Linux NFS client provides a way to make locks local. This means, the
+applications can lock files, but such locks provide exclusion only against
+other applications running on the same client. Remote applications are not
+affected by these locks.
+.IP
+If this option is not specified, or if
+.B none
+is specified, the client assumes that the locks are not local.
+.IP
+If
+.BR all
+is specified, the client assumes that both flock and POSIX locks are local.
+.IP
+If
+.BR flock
+is specified, the client assumes that only flock locks are local and uses
+NLM sideband protocol to lock files when POSIX locks are used.
+.IP
+If
+.BR posix
+is specified, the client assumes that POSIX locks are local and uses NLM
+sideband protocol to lock files when flock locks are used.
+.IP
+To support legacy flock behavior similar to that of NFS clients < 2.6.12, use
+'local_lock=flock'. This option is required when exporting NFS mounts via
+Samba as Samba maps Windows share mode locks as flock. Since NFS clients >
+2.6.12 implement flock by emulating POSIX locks, this will result in
+conflicting locks.
+.IP
+NOTE: When used together, the 'local_lock' mount option will be overridden
+by 'nolock'/'lock' mount option.
+.SS "Options for NFS version 4 only"
 Use these options, along with the options in the first subsection above,
-for NFSv4 only. They will be ignored with older versions.
+for NFS version 4 and newer.
 .TP 1.5i
 .BI proto= netid
 The transport protocol name and protocol family the NFS client uses
@@ -1480,32 +1523,54 @@ of Access Control Lists that are semantically richer than POSIX ACLs.
 NFS version 4 ACLs are not fully compatible with POSIX ACLs; as such,
 some translation between the two is required
 in an environment that mixes POSIX ACLs and NFS version 4.
-.SH FILES
-.TP 1.5i
-.I /etc/fstab
-file system table
-.SH BUGS
-The generic
-.B remount
-option is not fully supported.
-Generic options, such as
-.BR rw " and " ro
-can be modified using the
-.B remount
-option,
-but NFS-specific options are not all supported.
+.SH "THE REMOUNT OPTION"
+Generic mount options such as
+.BR rw " and " sync
+can be modified on NFS mount points using the
+.BR remount
+option.
+See
+.BR mount (8)
+for more information on generic mount options.
+.P
+With few exceptions, NFS-specific options
+are not able to be modified during a remount.
 The underlying transport or NFS version
 cannot be changed by a remount, for example.
+.P
 Performing a remount on an NFS file system mounted with the
 .B noac
 option may have unintended consequences.
 The
 .B noac
-option is a mixture of a generic option,
+option is a combination of the generic option
 .BR sync ,
-and an NFS-specific option
+and the NFS-specific option
 .BR actimeo=0 .
+.SS "Unmounting after a remount"
+For mount points that use NFS versions 2 or 3, the NFS umount subcommand
+depends on knowing the original set of mount options used to perform the
+MNT operation.
+These options are stored on disk by the NFS mount subcommand,
+and can be erased by a remount.
 .P
+To ensure that the saved mount options are not erased during a remount,
+specify either the local mount directory, or the server hostname and
+export pathname, but not both, during a remount.  For example,
+.P
+.NF
+.TA 2.5i
+       mount -o remount,ro /mnt
+.FI
+.P
+merges the mount option
+.B ro
+with the mount options already saved on disk for the NFS server mounted at /mnt.
+.SH FILES
+.TP 1.5i
+.I /etc/fstab
+file system table
+.SH BUGS
 Before 2.4.7, the Linux NFS client did not support NFS over TCP.
 .P
 Before 2.4.20, the Linux NFS client used a heuristic
index 1514340..8cd2852 100644 (file)
 #include "nls.h"
 
 #include "mount_constants.h"
+#include "nfs_mount.h"
 #include "mount.h"
 #include "error.h"
 #include "network.h"
 #include "parse_opt.h"
 #include "parse_dev.h"
+#include "utils.h"
+
+#define MOUNTSFILE     "/proc/mounts"
+#define LINELEN                (4096)
 
 #if !defined(MNT_FORCE)
 /* dare not try to include <linux/mount.h> -- lots of errors */
@@ -109,7 +114,7 @@ static int del_mtab(const char *spec, const char *node)
                        res = try_remount(spec, node);
                        if (res)
                                goto writemtab;
-                       return 0;
+                       return EX_SUCCESS;
                } else
                        umnt_err = errno;
        }
@@ -127,7 +132,7 @@ static int del_mtab(const char *spec, const char *node)
        }
 
        if (res >= 0)
-               return 0;
+               return EX_SUCCESS;
 
        if (umnt_err)
                umount_error(umnt_err, node);
@@ -135,110 +140,88 @@ static int del_mtab(const char *spec, const char *node)
 }
 
 /*
- * Discover mount server's hostname/address by examining mount options
- *
- * Returns a pointer to a string that the caller must free, on
- * success; otherwise NULL is returned.
- */
-static char *nfs_umount_hostname(struct mount_options *options,
-                                char *hostname)
-{
-       char *option;
-
-       option = po_get(options, "mountaddr");
-       if (option)
-               goto out;
-       option = po_get(options, "mounthost");
-       if (option)
-               goto out;
-       option = po_get(options, "addr");
-       if (option)
-               goto out;
-
-       return hostname;
-
-out:
-       free(hostname);
-       return strdup(option);
-}
-
-/*
- * Returns EX_SUCCESS if mount options and device name have been
- * parsed successfully; otherwise EX_FAIL.
- */
-static int nfs_umount_do_umnt(struct mount_options *options,
-                             char **hostname, char **dirname)
-{
-       union {
-               struct sockaddr         sa;
-               struct sockaddr_in      s4;
-               struct sockaddr_in6     s6;
-       } address;
-       struct sockaddr *sap = &address.sa;
-       socklen_t salen = sizeof(address);
-       struct pmap nfs_pmap, mnt_pmap;
-       sa_family_t family;
-
-       if (!nfs_options2pmap(options, &nfs_pmap, &mnt_pmap))
-               return EX_FAIL;
-
-       /* Skip UMNT call for vers=4 mounts */
-       if (nfs_pmap.pm_vers == 4)
-               return EX_SUCCESS;
-
-       *hostname = nfs_umount_hostname(options, *hostname);
-       if (!*hostname) {
-               nfs_error(_("%s: out of memory"), progname);
-               return EX_FAIL;
-       }
-
-       if (!nfs_mount_proto_family(options, &family))
-               return 0;
-       if (!nfs_lookup(*hostname, family, sap, &salen))
-               /* nfs_lookup reports any errors */
-               return EX_FAIL;
-
-       if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) == 0)
-               /* nfs_advise_umount reports any errors */
-               return EX_FAIL;
-
-       return EX_SUCCESS;
-}
-
-/*
- * Pick up certain mount options used during the original mount
- * from /etc/mtab.  The basics include the server's IP address and
- * the server pathname of the share to unregister.
+ * Detect NFSv4 mounts.
  *
- * These options might also describe the mount port, mount protocol
- * version, and transport protocol used to punch through a firewall.
- * We will need this information to get through the firewall again
- * to do the umount.
+ * Consult /proc/mounts to determine if the mount point
+ * is an NFSv4 mount.  The kernel is authoritative about
+ * what type of mount this is.
  *
- * Note that option parsing failures won't necessarily cause the
- * umount request to fail.  Those values will be left zero in the
- * pmap tuple.  If the GETPORT call later fails to disambiguate them,
- * then we fail.
+ * Returns 1 if "mc" is an NFSv4 mount, zero if not, and
+ * -1 if some error occurred.
  */
-static int nfs_umount23(const char *devname, char *string)
+static int nfs_umount_is_vers4(const struct mntentchn *mc)
 {
-       char *hostname, *dirname;
-       struct mount_options *options;
-       int result = EX_FAIL;
+       char buffer[LINELEN], *next;
+       int retval;
+       FILE *f;
+
+       if ((f = fopen(MOUNTSFILE, "r")) == NULL) {
+               fprintf(stderr, "%s: %s\n",
+                       MOUNTSFILE, strerror(errno));
+               return -1;
+       }
 
-       if (!nfs_parse_devname(devname, &hostname, &dirname))
-               return EX_USAGE;
+       retval = -1;
+       while (fgets(buffer, sizeof(buffer), f) != NULL) {
+               char *device, *mntdir, *type, *flags;
+               struct mount_options *options;
+               char *line = buffer;
+
+               next = strchr(line, '\n');
+               if (next != NULL)
+                       *next = '\0';
+
+               device = strtok(line, " \t");
+               if (device == NULL)
+                       continue;
+               mntdir = strtok(NULL, " \t");
+               if (mntdir == NULL)
+                       continue;
+               if (strcmp(device, mc->m.mnt_fsname) != 0 &&
+                   strcmp(mntdir, mc->m.mnt_dir) != 0)
+                       continue;
+
+               type = strtok(NULL, " \t");
+               if (type == NULL)
+                       continue;
+               if (strcmp(type, "nfs4") == 0)
+                       goto out_nfs4;
+
+               flags = strtok(NULL, " \t");
+               if (flags == NULL)
+                       continue;
+               options = po_split(flags);
+               if (options != NULL) {
+                       unsigned long version;
+                       int rc;
+
+                       rc = nfs_nfs_version(options, &version);
+                       po_destroy(options);
+                       if (rc && version == 4)
+                               goto out_nfs4;
+               }
 
-       options = po_split(string);
-       if (options) {
-               result = nfs_umount_do_umnt(options, &hostname, &dirname);
-               po_destroy(options);
-       } else
-               nfs_error(_("%s: option parsing error"), progname);
+               goto out_nfs;
+       }
+       if (retval == -1)
+               fprintf(stderr, "%s was not found in %s\n",
+                       mc->m.mnt_dir, MOUNTSFILE);
 
-       free(hostname);
-       free(dirname);
-       return result;
+out:
+       fclose(f);
+       return retval;
+
+out_nfs4:
+       if (verbose)
+               fprintf(stderr, "NFSv4 mount point detected\n");
+       retval = 1;
+       goto out;
+
+out_nfs:
+       if (verbose)
+               fprintf(stderr, "Legacy NFS mount point detected\n");
+       retval = 0;
+       goto out;
 }
 
 static struct option umount_longopts[] =
@@ -251,17 +234,6 @@ static struct option umount_longopts[] =
   { NULL, 0, 0, 0 }
 };
 
-static void umount_usage(void)
-{
-       printf(_("usage: %s dir [-fvnrlh]\n"), progname);
-       printf(_("options:\n\t-f\t\tforce unmount\n"));
-       printf(_("\t-v\tverbose\n"));
-       printf(_("\t-n\tDo not update /etc/mtab\n"));
-       printf(_("\t-r\tremount\n"));
-       printf(_("\t-l\tlazy unmount\n"));
-       printf(_("\t-h\tprint this help\n\n"));
-}
-
 int nfsumount(int argc, char *argv[])
 {
        int c, ret;
@@ -362,16 +334,25 @@ int nfsumount(int argc, char *argv[])
                }
        }
 
-       ret = 0;
+       ret = EX_SUCCESS;
        if (mc) {
-               if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0)
-                       /* We ignore the error from nfs_umount23.
-                        * If the actual umount succeeds (in del_mtab),
-                        * we don't want to signal an error, as that
-                        * could cause /sbin/mount to retry!
-                        */
-                       nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
-               ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir) ?: ret;
+               if (!lazy) {
+                       switch (nfs_umount_is_vers4(mc)) {
+                       case 0:
+                               /* We ignore the error from nfs_umount23.
+                                * If the actual umount succeeds (in del_mtab),
+                                * we don't want to signal an error, as that
+                                * could cause /sbin/mount to retry!
+                                */
+                               nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
+                               break;
+                       case 1:
+                               break;
+                       default:
+                               return EX_FAIL;
+                       }
+               }
+               ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
        } else if (*spec != '/') {
                if (!lazy)
                        ret = nfs_umount23(spec, "tcp,v3");
index f0918f7..ab869d9 100644 (file)
@@ -508,7 +508,7 @@ po_found_t po_get_numeric(struct mount_options *options, char *keyword, long *va
 int po_rightmost(struct mount_options *options, const char *keys[])
 {
        struct mount_option *option;
-       unsigned int i;
+       int i;
 
        if (options) {
                for (option = options->tail; option; option = option->prev) {
index 50a1a2a..f1aa503 100644 (file)
 #include "parse_dev.h"
 #include "conffile.h"
 
-#ifndef HAVE_DECL_AI_ADDRCONFIG
-#define AI_ADDRCONFIG  0
-#endif
-
 #ifndef NFS_PROGRAM
 #define NFS_PROGRAM    (100003)
 #endif
@@ -114,7 +110,7 @@ static void nfs_default_version(struct nfsmount_info *mi)
        }
 }
 #else
-inline void nfs_default_version(struct nfsmount_info *mi) {}
+inline void nfs_default_version(__attribute__ ((unused)) struct nfsmount_info *mi) {}
 #endif /* MOUNT_CONFIG */
 
 /*
@@ -123,10 +119,12 @@ inline void nfs_default_version(struct nfsmount_info *mi) {}
  * Returns a time_t timeout timestamp, in seconds.
  */
 static time_t nfs_parse_retry_option(struct mount_options *options,
-                                    unsigned int timeout_minutes)
+                                    const time_t default_timeout)
 {
+       time_t timeout_minutes;
        long tmp;
 
+       timeout_minutes = default_timeout;
        switch (po_get_numeric(options, "retry", &tmp)) {
        case PO_NOT_FOUND:
                break;
@@ -135,6 +133,7 @@ static time_t nfs_parse_retry_option(struct mount_options *options,
                        timeout_minutes = tmp;
                        break;
                }
+               /*FALLTHROUGH*/
        case PO_BAD_VALUE:
                if (verbose)
                        nfs_error(_("%s: invalid retry timeout was specified; "
@@ -142,7 +141,7 @@ static time_t nfs_parse_retry_option(struct mount_options *options,
                break;
        }
 
-       return time(NULL) + (time_t)(timeout_minutes * 60);
+       return time(NULL) + (timeout_minutes * 60);
 }
 
 /*
@@ -343,7 +342,6 @@ static int nfs_validate_options(struct nfsmount_info *mi)
 {
        struct addrinfo hint = {
                .ai_protocol    = (int)IPPROTO_UDP,
-               .ai_flags       = AI_ADDRCONFIG,
        };
        sa_family_t family;
        int error;
@@ -570,16 +568,18 @@ static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts)
        char *options = NULL;
        int result;
 
+       if (mi->fake)
+               return 1;
+
        if (po_join(opts, &options) == PO_FAILED) {
                errno = EIO;
                return 0;
        }
 
-       if (mi->fake)
-               return 1;
-
        result = mount(mi->spec, mi->node, mi->type,
                        mi->flags & ~(MS_USER|MS_USERS), options);
+       free(options);
+
        if (verbose && result) {
                int save = errno;
                nfs_error(_("%s: mount(2): %s"), progname, strerror(save));
@@ -650,7 +650,7 @@ out_fail:
 static int nfs_try_mount_v3v2(struct nfsmount_info *mi)
 {
        struct addrinfo *ai;
-       int ret;
+       int ret = 0;
 
        for (ai = mi->address; ai != NULL; ai = ai->ai_next) {
                ret = nfs_do_mount_v3v2(mi, ai->ai_addr, ai->ai_addrlen);
@@ -737,7 +737,7 @@ out_fail:
 static int nfs_try_mount_v4(struct nfsmount_info *mi)
 {
        struct addrinfo *ai;
-       int ret;
+       int ret = 0;
 
        for (ai = mi->address; ai != NULL; ai = ai->ai_next) {
                ret = nfs_do_mount_v4(mi, ai->ai_addr, ai->ai_addrlen);
diff --git a/utils/mount/utils.c b/utils/mount/utils.c
new file mode 100644 (file)
index 0000000..298db39
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "sockaddr.h"
+#include "nfs_mount.h"
+#include "nls.h"
+#include "xcommon.h"
+#include "version.h"
+#include "error.h"
+#include "utils.h"
+#include "mount.h"
+#include "network.h"
+#include "parse_dev.h"
+
+extern int verbose;
+extern char *progname;
+
+/*
+ * Choose the version of the nfs_mount_data structure that is appropriate
+ * for the kernel that is doing the mount.
+ *
+ * NFS_MOUNT_VERSION:          maximum version supported by these sources
+ * nfs_mount_data_version:     maximum version supported by the running kernel
+ */
+int discover_nfs_mount_data_version(int *string_ver)
+{
+       unsigned int kernel_version = linux_version_code();
+       int ver = 0;
+
+       *string_ver = 0;
+
+       if (kernel_version) {
+               if (kernel_version < MAKE_VERSION(2, 1, 32))
+                       ver = 1;
+               else if (kernel_version < MAKE_VERSION(2, 2, 18))
+                       ver = 3;
+               else if (kernel_version < MAKE_VERSION(2, 3, 0))
+                       ver = 4;
+               else if (kernel_version < MAKE_VERSION(2, 3, 99))
+                       ver = 3;
+               else if (kernel_version < MAKE_VERSION(2, 6, 3))
+                       ver = 4;
+               else
+                       ver = 6;
+       }
+       if (ver > NFS_MOUNT_VERSION)
+               ver = NFS_MOUNT_VERSION;
+       else
+               if (kernel_version > MAKE_VERSION(2, 6, 22))
+                       (*string_ver)++;
+
+       return ver;
+}
+
+void print_one(char *spec, char *node, char *type, char *opts)
+{
+       if (!verbose)
+               return;
+
+       if (opts)
+               printf(_("%s on %s type %s (%s)\n"), spec, node, type, opts);
+       else
+               printf(_("%s on %s type %s\n"), spec, node, type);
+}
+
+void mount_usage(void)
+{
+       printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"),
+               progname);
+       printf(_("options:\n"));
+       printf(_("\t-r\t\tMount file system readonly\n"));
+       printf(_("\t-v\t\tVerbose\n"));
+       printf(_("\t-V\t\tPrint version\n"));
+       printf(_("\t-w\t\tMount file system read-write\n"));
+       printf(_("\t-f\t\tFake mount, do not actually mount\n"));
+       printf(_("\t-n\t\tDo not update /etc/mtab\n"));
+       printf(_("\t-s\t\tTolerate sloppy mount options rather than fail\n"));
+       printf(_("\t-h\t\tPrint this help\n"));
+       printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n"));
+}
+
+void umount_usage(void)
+{
+       printf(_("usage: %s dir [-fvnrlh]\n"), progname);
+       printf(_("options:\n\t-f\t\tforce unmount\n"));
+       printf(_("\t-v\tverbose\n"));
+       printf(_("\t-n\tDo not update /etc/mtab\n"));
+       printf(_("\t-r\tremount\n"));
+       printf(_("\t-l\tlazy unmount\n"));
+       printf(_("\t-h\tprint this help\n\n"));
+}
+
+int chk_mountpoint(const char *mount_point)
+{
+       struct stat sb;
+
+       if (stat(mount_point, &sb) < 0){
+               mount_error(NULL, mount_point, errno);
+               return 1;
+       }
+       if (S_ISDIR(sb.st_mode) == 0){
+               mount_error(NULL, mount_point, ENOTDIR);
+               return 1;
+       }
+       if (access(mount_point, X_OK) < 0) {
+               mount_error(NULL, mount_point, errno);
+               return 1;
+       }
+
+       return 0;
+}
+
+/*
+ * Pick up certain mount options used during the original mount
+ * from /etc/mtab.  The basics include the server's IP address and
+ * the server pathname of the share to unregister.
+ *
+ * These options might also describe the mount port, mount protocol
+ * version, and transport protocol used to punch through a firewall.
+ * We will need this information to get through the firewall again
+ * to do the umount.
+ *
+ * Note that option parsing failures won't necessarily cause the
+ * umount request to fail.  Those values will be left zero in the
+ * pmap tuple.  If the GETPORT call later fails to disambiguate them,
+ * then we fail.
+ */
+int nfs_umount23(const char *devname, char *string)
+{
+       char *hostname = NULL, *dirname = NULL;
+       struct mount_options *options;
+       int result = EX_FAIL;
+
+       if (!nfs_parse_devname(devname, &hostname, &dirname))
+               return EX_USAGE;
+
+       options = po_split(string);
+       if (options) {
+               result = nfs_umount_do_umnt(options, &hostname, &dirname);
+               po_destroy(options);
+       } else
+               nfs_error(_("%s: option parsing error"), progname);
+
+       free(hostname);
+       free(dirname);
+       return result;
+}
diff --git a/utils/mount/utils.h b/utils/mount/utils.h
new file mode 100644 (file)
index 0000000..3fcd504
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * utils.h -- misc utils for mount and umount
+ *
+ * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef _NFS_UTILS_MOUNT_UTILS_H
+#define _NFS_UTILS_MOUNT_UTILS_H
+
+#include "parse_opt.h"
+
+int discover_nfs_mount_data_version(int *string_ver);
+void print_one(char *spec, char *node, char *type, char *opts);
+void mount_usage(void);
+void umount_usage(void);
+int chk_mountpoint(const char *mount_point);
+
+int nfs_umount23(const char *devname, char *string);
+
+#endif /* !_NFS_UTILS_MOUNT_UTILS_H */
index 46552a1..af61a6f 100644 (file)
@@ -42,9 +42,9 @@ static inline unsigned int linux_version_code(void)
        if (uname(&my_utsname))
                return 0;
 
-       p = atoi(strtok(my_utsname.release, "."));
-       q = atoi(strtok(NULL, "."));
-       r = atoi(strtok(NULL, "."));
+       p = (unsigned int)atoi(strtok(my_utsname.release, "."));
+       q = (unsigned int)atoi(strtok(NULL, "."));
+       r = (unsigned int)atoi(strtok(NULL, "."));
        return MAKE_VERSION(p, q, r);
 }
 
index f70f4d6..d2ae456 100644 (file)
@@ -64,6 +64,7 @@ enum nfsd_fsid {
  */
 static int cache_export_ent(char *domain, struct exportent *exp, char *p);
 
+#define INITIAL_MANAGED_GROUPS 100
 
 char *lbuf  = NULL;
 int lbuflen = 0;
@@ -114,7 +115,7 @@ static void auth_unix_ip(FILE *f)
 
        qword_print(f, "nfsd");
        qword_print(f, ipaddr);
-       qword_printint(f, time(0)+30*60);
+       qword_printuint(f, time(0) + DEFAULT_TTL);
        if (use_ipaddr)
                qword_print(f, ipaddr);
        else if (client)
@@ -134,11 +135,23 @@ static void auth_unix_gid(FILE *f)
         */
        uid_t uid;
        struct passwd *pw;
-       gid_t glist[100], *groups = glist;
-       int ngroups = 100;
+       static gid_t *groups = NULL;
+       static int groups_len = 0;
+       gid_t *more_groups;
+       int ngroups;
        int rv, i;
        char *cp;
 
+       if (groups_len == 0) {
+               groups = malloc(sizeof(gid_t) * INITIAL_MANAGED_GROUPS);
+               if (!groups)
+                       return;
+
+               groups_len = INITIAL_MANAGED_GROUPS;
+       }
+
+       ngroups = groups_len;
+
        if (readline(fileno(f), &lbuf, &lbuflen) != 1)
                return;
 
@@ -151,17 +164,20 @@ static void auth_unix_gid(FILE *f)
                rv = -1;
        else {
                rv = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
-               if (rv == -1 && ngroups >= 100) {
-                       groups = malloc(sizeof(gid_t)*ngroups);
-                       if (!groups)
+               if (rv == -1 && ngroups >= groups_len) {
+                       more_groups = realloc(groups, sizeof(gid_t)*ngroups);
+                       if (!more_groups)
                                rv = -1;
-                       else
+                       else {
+                               groups = more_groups;
+                               groups_len = ngroups;
                                rv = getgrouplist(pw->pw_name, pw->pw_gid,
                                                  groups, &ngroups);
+                       }
                }
        }
        qword_printuint(f, uid);
-       qword_printuint(f, time(0)+30*60);
+       qword_printuint(f, time(0) + DEFAULT_TTL);
        if (rv >= 0) {
                qword_printuint(f, ngroups);
                for (i=0; i<ngroups; i++)
@@ -169,9 +185,6 @@ static void auth_unix_gid(FILE *f)
        } else
                qword_printuint(f, 0);
        qword_eol(f);
-
-       if (groups != glist)
-               free(groups);
 }
 
 #if USE_BLKID
@@ -328,63 +341,49 @@ static char *next_mnt(void **v, char *p)
        return me->mnt_dir;
 }
 
-static void nfsd_fh(FILE *f)
+/* True iff e1 is a child of e2 and e2 has crossmnt set: */
+static bool subexport(struct exportent *e1, struct exportent *e2)
 {
-       /* 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;
-       unsigned int dev, major=0, minor=0;
-       unsigned int inode=0;
-       unsigned long long inode64;
-       unsigned int fsidnum=0;
-       char fsid[32];
-       struct exportent *found = NULL;
-       struct addrinfo *ai = NULL;
-       char *found_path = NULL;
-       nfs_export *exp;
-       int i;
-       int dev_missing = 0;
-       int uuidlen = 0;
-       char *fhuuid = NULL;
+       char *p1 = e1->e_path, *p2 = e2->e_path;
+       int l2 = strlen(p2);
 
-       if (readline(fileno(f), &lbuf, &lbuflen) != 1)
-               return;
+       return e2->e_flags & NFSEXP_CROSSMOUNT
+              && strncmp(p1, p2, l2) == 0
+              && p1[l2] == '/';
+}
 
-       xlog(D_CALL, "nfsd_fh: inbuf '%s'", lbuf);
+struct parsed_fsid {
+       int fsidtype;
+       /* We could use a union for this, but it would be more
+        * complicated; why bother? */
+       unsigned int inode;
+       unsigned int minor;
+       unsigned int major;
+       unsigned int fsidnum;
+       int uuidlen;
+       char *fhuuid;
+};
 
-       cp = lbuf;
-       
-       dom = malloc(strlen(cp));
-       if (dom == NULL)
-               return;
-       if (qword_get(&cp, dom, strlen(cp)) <= 0)
-               goto out;
-       if (qword_get_int(&cp, &fsidtype) != 0)
-               goto out;
-       if (fsidtype < 0 || fsidtype > 7)
-               goto out; /* unknown type */
-       if ((fsidlen = qword_get(&cp, fsid, 32)) <= 0)
-               goto out;
+int parse_fsid(int fsidtype, int fsidlen, char *fsid, struct parsed_fsid *parsed)
+{
+       unsigned int dev;
+      &nbs