Skip to content

Instantly share code, notes, and snippets.

@NiceGuyIT
Forked from thwarted/auto.nfs4
Last active August 29, 2015 14:12
Show Gist options
  • Save NiceGuyIT/5cb5703dc497bac2eefb to your computer and use it in GitHub Desktop.
Save NiceGuyIT/5cb5703dc497bac2eefb to your computer and use it in GitHub Desktop.
#!/bin/bash
# name this script /etc/auto.nfs4 and make it executable
# /bin is too restrictive
#PATH=/bin
tryconnect() {
local host="$1"
if [[ -n "$(which nc 2>/dev/null)" ]]
then
nc -w 1 "$host" 2049 < /dev/null >/dev/null 2>&1;
elif [[ -n "$(which ncat 2>/dev/null)" ]]
then
# This hangs in certain situations
# For example, connecting to NFS on CentOS 6.5 from ncat 5.51 on CentOS 6.5 hangs when using /dev/null
# Using /dev/zero or echo'ing some CRs works
# ncat 6.40 on CentOS 7 doesn't have this problem
if [[ "$(ncat --version 2>&1 | awk '{print $3}')" > "6" ]]
then
ncat -w 1 "$host" 2049 < /dev/null >/dev/null 2>&1;
else
ncat -w 1 "$host" 2049 < /dev/zero >/dev/null 2>&1;
fi
else
# if you don't have nmap-ncat, but your bash does support pseudo-redirection
# from /dev/tcp, you can use the following
timeout 1 bash -c "cat < /dev/null > /dev/tcp/$host/2049" >/dev/null
fi
}
validkey() {
# make sure the key isn't empty and contains only
# alphanumeric, dot, and dash (valid DNS names)
local key="$1"
[[ -n "$key" ]] &&
echo "$key" | grep -sqvE '[^[:alnum:].-]'
}
key="$1"
if validkey "$key"; then
if tryconnect "$key"; then
logger -t auto.nfs4 "$key listening on 2049, trying to automount"
echo -fstype=nfs4,hard,intr,nodev,nosuid $key:/
exit 0
fi
logger -t auto.nfs4 "$key not listening on port 2049, assuming no nfsv4 server"
else
logger -t auto.nfs4 "\"$key\" is invalid, ignoring"
fi
exit 1
# If auto.master contains
# +dir:/etc/auto.master.d
# then this file can go in /etc/auto.master.d/net.autofs
/net program:/etc/auto.nfs4 fstype=nfs4 --timeout=30 noatime
# otherwise, put the above line in /etc/auto.master
# you'll also want to comment out any other /net entries
# in /etc/auto.master
# the --timeout=30 above will have autofs umount the filesystem
# after 30 seconds of inactivity. you may want to increase that.

autofs supports a -hosts map, which looks like this:

#
# NOTE: mounts done from a hosts map will be mounted with the
#       "nosuid" and "nodev" options unless the "suid" and "dev"
#       options are explicitly given.
#

/net   -hosts

This apparently invokes /etc/auto.net which uses (k)showmount to get a list of exported filesystems from the remote machine. Unfortunately, this requires the nfsv3 mountd to be running/available on the remote machine, which you may not have available on a pure nfsv4 setup.

Because of the way nfsv4 works with the pseudo-root filesystem that dynamically exposes the list of available filesystems on a per-client basis, just the root export needs to be exposed. The server enumerates the available filesystems for the client via the pseudo-root, so this just needs to know about, and attempt to mount, targetmachine:/, not all the paths listed in /etc/exports on the remote machine as is necessary for nfsv3.

But we only want to attempt to mount it if it looks like nfsv4 is running, otherwise the client program could pause while attempting to connect to an inaccessible machine. A simplistic TCP connect test, with a 1 second time out, is used to see if there is an nfsv4 server on the remote machine.

Inspiration from https://bugzilla.redhat.com/show_bug.cgi?id=643142

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment