You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.3 KiB

#!/bin/sh
. /lib/dracut-lib
PATH=$PATH:/sbin:/usr/sbin
# XXX needs error handling like ifup/dhclient-script
# XXX need to lock our attempts if we're doing the mount here
getarg rdnetdebug && {
exec > /tmp/nfsroot.$1.$$.out
exec 2>> /tmp/nfsroot.$1.$$.out
set -x
}
[ "$NFS_LOCKED" ] || {
NFS_LOCKED=true
export NFS_LOCKED
exec flock -xo /tmp/nfs.lock -c "$0 $*"
exit 1
}
[ -e /tmp/nfsdone ] && exit 0
nfs_done() {
>/tmp/nfsdone
exit 0
}
root=$(getarg root)
case $root in
nfs|/dev/nfs) type=nfs ;;
nfs4|/dev/nfs4) type=nfs4 ;;
auto|'') type=auto ;;
esac
rootfstype=$(getarg rootfstype)
case $rootfstype in
nfs|nfs4|auto) type=$rootfstype ;;
esac
# If we're not doing NFS at all, don't keep banging our head
[ -n "$type" ] || nfs_done
[ -e /tmp/net.$1.dhcpopts ] && . /tmp/net.$1.dhcpopts
nfsroot=$(getarg nfsroot)
[ -n "$nfsroot" ] || nfsroot="$new_root_path"
[ -n "$nfsroot" ] || nfs_done
# check for IP address at front, if there is none, use
# new_dhcp_server_identifier
#
# XXX kernel nfsroot uses , to separate NFS options at end
#
nfsserver=${nfsroot%%:*}; nfsroot=${nfsroot#*:}
nfspath=${nfsroot%%:*}
flags=${nfsroot#*:}
[ "$nfsserver" = "$nfspath" ] && nfsserver=$new_dhcp_server_identifier
[ "$nfspath" = "$flags" ] && unset flags
[ -n "$nfsserver" ] || no_nfs
# look through the flags and see if any are overridden by the command line
while [ -n "$flags" ]; do
f=${flags%%,*}; flags=${flags#*,}
[ "$f" = "nfs" -o "$f" = "nfs4" ] && {
[ "$type" = "auto" ] && type=$f
continue
}
[ "$f" = "ro" -o "$f" = "rw" ] && {
nfsrw=$f
continue
}
[ "$f" = "lock" -o "$f" = "nolock" ] && {
nfslock=$f
continue
}
nfsflags=${nfsflags+$nfsflags,}$f
done
getarg ro && nfsrw=ro
getarg rw && nfsrw=rw
nfsflags=${nfsflags+$nfsflags,}${nfsrw}
# load our modules explicitly, so we can fail fast in the future
modprobe nfs || nfs_done
# XXX don't forget to move /var/lib/nfs/rpc_pipefs to new /
# XXX need host name set before now?
# Start rpcbind and rpc.statd as mount won't let us use locks on a NFSv4
# filesystem without talking to them, even though they are unneeded
# XXX occasionally saw 'rpcbind: fork failed: No such device' -- why?
[ -n "$(pidof rpcbind)" ] || rpcbind
[ -n "$(pidof rpc.statd)" ] || rpc.statd
# XXX should I do rpc.idmapd here, or wait and start in the new root
# XXX waiting assumes root can read everything it needs right up until
# XXX we start it...
# XXX really, want to retry in a loop I think, but not here...
[ "$type" = "nfs4" -o "$type" = "auto" ] && {
# XXX really needed? Do we need non-root users before we start it in
# XXX the real root image?
[ -n "$(pidof rpc.idmapd)" ] || rpc.idmapd
# NFSv4 does locks internally
mount -t nfs4 -o${nfsflags}${nfslock+,$nfslock} \
$nfsserver:$nfspath /sysroot && nfs_done
# If we're specified to be NFSv4, then stop when we fail
# Don't mark us done, as this may be transient
[ "$type" = "nfs4" ] && exit 0
}
# we're NFSv{2,3} or auto and NFSv4 failed. We don't support using locks
# on NFSv{2,3} because that requires a helper to transfer the rpcbind state
# rpcbind to the new root
[ -z "$nfslock" -o "$nfslock" = "lock" ] &&
echo "Locks unsupported on NFSv{2,3}, using nolock" 1>&2
mount -t nfs -onolock,$nfsflags $nfsserver:$nfspath /sysroot && nfs_done
exit 0