gssd: always reply to rpc-pipe requests from kernel.

Sometimes gssd will open a new rpc-pipe but never read requests from it
or reply to them.  This causes the kernel to wait forever for a reply.

In particular, if a filesystem is mounted by IP, and the IP has no
hostname recorded in /etc/hosts or DNS, then gssd will not listen to
requests and the mount will hang indefinitely.

The comment in process_clnt_dir() for the "fail_keep_client:" branch
suggests that it is for the case where we couldn't open some
subdirectories.  However it is currently also taken if reverse DNS
lookup fails (as well as some other lookup failures).  Those failures
should not be treated the same as failure-to-open directories.

So this patch causes a failure from read_service_info() to *not* be
reported by process_clnt_dir_files.  This ensures that
insert_clnt_poll()
will be called and requests will be handled.

In handle_gssd_upcall, the current error path (taken when the mech is
not "krb5") does not reply to the upcall.  This is wrong.  A reply is
always appropriate.  The only replies which aren't treated as
transient errors are EACCES and EKEYEXPIRED, so we return the former.

If read_service_info() fails then ->servicename will be NULL which will
cause process_krb5_upcall() (quite reasonably) to become confused.  So
in that case we don't even try to process the up-call but just reply
with EACCES.

As clp->servicename==NULL is no longer treated as fatal, it is not
appropraite to use it to test if read_service_info() has been already
called on a client.  Instread test clp->prog.

Finally, the error path of read_service_info() will close 'fd' if it
isn't -1, so when we close it, we should set fd to -1.

Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Steve Dickson <steved@redhat.com>
gssd: Fix file descriptor leak of old pipe dirs

gssd doesn't properly clean up internal state for old pipes and never
closes the (since deleted) clnt_info directory. This leads to eventual
fd exhaustion.

To reproduce, run a lot of mount / umounts in a loop and watch the
output of 'ls /proc/$PID/fdinfo | wc -l' (where PID is the pid of gssd)
steadily grow until gssd eventually crashes with "Too many open files".

This regression was introduced by 841e83c1, which was trying to fix a
similar bug in the skip matching logic of update_old_clients. The
problem with that patch is that pdir will never match dirname,
because dirname is "<pname>/clntXXX".

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
mount.nfs: Recognize v4.x mount options

The kernel understands text options of the form "v4.x" (ie "v4.1"), but
mount.nfs does not and this leads to weird errors when the requested
mount fails: a line in dmesg about version 3 not supporting
minorversions
and mount.nfs returning EINVAL no matter what the real error was.

This happens because mount.nfs thinks no version was specified so it
starts
probing other versions which conflicts with the v4.X option once it gets
parsed by the kernel.

$ sudo mount -v -o v4.1 zero:/invalid_export /mnt
mount.nfs: timeout set for Wed Nov 13 10:09:48 2013
mount.nfs: trying text-based options
'v4.1,vers=4,addr=192.168.100.10,clientaddr=192.168.100.11'
mount.nfs: mount(2): No such file or directory
mount.nfs: trying text-based options 'v4.1,addr=192.168.100.10'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: trying 192.168.100.10 prog 100003 vers 3 prot TCP port 2049
mount.nfs: prog 100005, trying vers=3, prot=17
mount.nfs: trying 192.168.100.10 prog 100005 vers 3 prot UDP port 20048
mount.nfs: mount(2): Invalid argument
mount.nfs: an incorrect mount option was specified

And you get this in dmesg:

NFS: mount option vers=3 does not support minorversion=1

but if you use another form of the same options, this doesn't happen:

$ sudo mount -v -o vers=4,minorversion=1 zero:/invalid_export /mnt
mount.nfs: timeout set for Wed Nov 13 10:10:28 2013
mount.nfs: trying text-based options
'vers=4,minorversion=1,addr=192.168.100.10,clientaddr=192.168.100.11'
mount.nfs: mount(2): No such file or directory
mount.nfs: mounting zero:/invalid_export failed, reason given by server:
No such file or directory

Acked-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Weston Andros Adamson <dros@netapp.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
nfs(5): Document the "migration" mount option

Support for NFSv4 migration was merged in 3.13.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
gssd: don't let spurious signals interrupt the wait after forking

Because gssd uses dnotify under the hood, it's easily possible that the
parent process can catch a signal while processing an upcall. If that
happens, then we'll currently exit the wait for the child task to exit,
and it'll end up as a zombie.

Fix this by ensuring that we only wait for the child to actually exit.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
nfs-utils: consolidate mydaemon() and release_parent() implementations

We currently have 2 cut-and-paste versions of this code. One for idmapd
and one for svcgssd.[1]

The two are basically equivalent but there are some small differences,
mostly related to how errors in that function are logged. svcgssd uses
printerr() with a priority of 1, which only prints errors if -v was
specified. That doesn't seem to be quite right. Daemonizing errors are
necessarily fatal and should be logged as such. The one for idmapd uses
err(), which always prints to stderr even though we have the xlog
facility set up. Since both have xlog configured at this point, log the
errors using xlog_err() instead.

The only other significant difference I see is that the idmapd version
will open "/" if it's unable to open "/dev/null". I believe that however
was a holdover from an earlier version of that function that did not
error out when we were unable to open a file descriptor. Since the
function does that now, I don't believe we need that fallback anymore.

[1]: technically, we have a third in statd too, but it's different
     enough that I don't want to touch it here.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
gssd: don't let parent exit until child has a chance to scan directory once

With some proposed kernel changes, it won't even attempt to upcall
sometimes if it doesn't appear that gssd is running. This means that
we have a theoretical race between gssd starting up at boot time and
the init process attempting to mount kerberized filesystems.

Fix this by switching gssd to use mydaemon() and having the child
only release the parent after it has processed the directory once.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
nfs(5): Treatment of *atime mount options

I was reminded recently that NFS treats file atime time stamps
differently than other filesystems.  It also ignores the generic
*atime mount options because it cannot support the atime semantics
of local filesystems.

We should document that somewhere.  nfs(5) seems like a logical
place for it.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
exportfs: modify can_test() to use LONG_MAX when appropriate

This patch is the nfs-utils patch corresponding to the kernel patch
commit 2f74f972 "sunrpc: prepare NFS for 2038". The kernel sunrpc
code needs to handle seconds since epoch greater than 2147483647.
This means functions that parse time as an int need to
handle it as time_t."

When appropriate exportfs should use LONG_MAX in can_test()
instead of INT_MAX.

Signed-off-by: Harshula Jayasuriya <harshula@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>