|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
|
|
|
|
. /lib/net-lib.sh
|
|
|
|
|
|
|
|
# TODO: make these things not pollute the calling namespace
|
|
|
|
|
|
|
|
# nfs_to_var NFSROOT [NETIF]
|
|
|
|
# use NFSROOT to set $nfs, $server, $path, and $options.
|
|
|
|
# NFSROOT is something like: nfs[4]:<server>:/<path>[:<options>|,<options>]
|
|
|
|
# NETIF is used to get information from DHCP options, if needed.
|
|
|
|
nfs_to_var() {
|
|
|
|
# Unfortunately, there's multiple styles of nfs "URL" in use, so we need
|
|
|
|
# extra functions to parse them into $nfs, $server, $path, and $options.
|
|
|
|
# FIXME: local netif=${2:-$netif}?
|
|
|
|
case "$1" in
|
|
|
|
nfs://*) rfc2224_nfs_to_var "$1" ;;
|
|
|
|
nfs:*[*) anaconda_nfsv6_to_var "$1" ;;
|
|
|
|
nfs:*:*:/*) anaconda_nfs_to_var "$1" ;;
|
|
|
|
*) nfsroot_to_var "$1" ;;
|
|
|
|
esac
|
|
|
|
# if anything's missing, try to fill it in from DHCP options
|
|
|
|
if [ -z "$server" ] || [ -z "$path" ]; then nfsroot_from_dhcp $2; fi
|
|
|
|
# if there's a "%s" in the path, replace it with the hostname/IP
|
|
|
|
if strstr "$path" "%s"; then
|
|
|
|
local node=""
|
|
|
|
read node < /proc/sys/kernel/hostname
|
|
|
|
[ "$node" = "(none)" ] && node=$(get_ip $2)
|
|
|
|
path=${path%%%s*}$node${path#*%s} # replace only the first %s
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# root=nfs:[<server-ip>:]<root-dir>[:<nfs-options>]
|
|
|
|
# root=nfs4:[<server-ip>:]<root-dir>[:<nfs-options>]
|
|
|
|
nfsroot_to_var() {
|
|
|
|
# strip nfs[4]:
|
|
|
|
local arg="$@:"
|
|
|
|
nfs="${arg%%:*}"
|
|
|
|
arg="${arg##$nfs:}"
|
|
|
|
|
|
|
|
# check if we have a server
|
Specify strstr tightly, add strglob/strglobin.
By convention, strstr should be a literal string match. Previously, it
would match as a glob pattern. Some code used that, so add new
functions strglob and strglobin to do what that code expects, and
specify them tightly too. strglob tests whether the glob pattern
matches the entire string (the name strglob is also used in the yorick
language, and that's what it does there), while strglobin tests whether
the glob pattern matches anywhere in the string.
Also tightens str_starts, str_ends, and str_replace to deal with
literal strings only. In a quick grep I did not find code that depended
on these functions matching globs.
Changes the call sites where strstr was used with glob patterns to use
strglobin or strglob as the intention seemed to be (or, in one case,
strstr with the * removed as it did not affect the result anyway).
11 years ago
|
|
|
if strstr "$arg" ':/' ; then
|
|
|
|
server="${arg%%:/*}"
|
|
|
|
arg="/${arg##*:/}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
path="${arg%%:*}"
|
|
|
|
|
|
|
|
# rest are options
|
|
|
|
options="${arg##$path}"
|
|
|
|
# strip leading ":"
|
|
|
|
options="${options##:}"
|
|
|
|
# strip ":"
|
|
|
|
options="${options%%:}"
|
|
|
|
|
|
|
|
# Does it really start with '/'?
|
|
|
|
[ -n "${path%%/*}" ] && path="error";
|
|
|
|
|
|
|
|
#Fix kernel legacy style separating path and options with ','
|
|
|
|
if [ "$path" != "${path#*,}" ] ; then
|
|
|
|
options=${path#*,}
|
|
|
|
path=${path%%,*}
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# RFC2224: nfs://<server>[:<port>]/<path>
|
|
|
|
rfc2224_nfs_to_var() {
|
|
|
|
nfs="nfs"
|
|
|
|
server="${1#nfs://}"
|
|
|
|
path="/${server#*/}"
|
|
|
|
server="${server%%/*}"
|
|
|
|
server="${server%%:}" # anaconda compat (nfs://<server>:/<path>)
|
|
|
|
local port="${server##*:}"
|
|
|
|
[ "$port" != "$server" ] && options="port=$port"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Anaconda-style path with options: nfs:<options>:<server>:/<path>
|
|
|
|
# (without mount options, anaconda is the same as dracut)
|
|
|
|
anaconda_nfs_to_var() {
|
|
|
|
nfs="nfs"
|
|
|
|
options="${1#nfs:}"
|
|
|
|
server="${options#*:}"
|
|
|
|
server="${server%:/*}"
|
|
|
|
options="${options%%:*}"
|
|
|
|
path="/${1##*:/}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# IPv6 nfs path will be treated separately
|
|
|
|
anaconda_nfsv6_to_var() {
|
|
|
|
nfs="nfs"
|
|
|
|
path="$1:"
|
|
|
|
options="${path#*:/}"
|
|
|
|
path="/${options%%:*}"
|
|
|
|
server="${1#*nfs:}"
|
|
|
|
if str_starts $server '['; then
|
|
|
|
server="${server%:/*}"
|
|
|
|
options="${options#*:*}"
|
|
|
|
else
|
|
|
|
server="${server%:/*}"
|
|
|
|
options="${server%%:*}"
|
|
|
|
server="${server#*:}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# nfsroot_from_dhcp NETIF
|
|
|
|
# fill in missing server/path from DHCP options.
|
|
|
|
nfsroot_from_dhcp() {
|
|
|
|
local f
|
|
|
|
for f in /tmp/net.$1.override /tmp/dhclient.$1.dhcpopts; do
|
|
|
|
[ -f $f ] && . $f
|
|
|
|
done
|
|
|
|
[ -n "$new_root_path" ] && nfsroot_to_var "$nfs:$new_root_path"
|
|
|
|
[ -z "$path" ] && [ "$(getarg root=)" == "/dev/nfs" ] && path=/tftpboot/%s
|
|
|
|
[ -z "$server" ] && server=$srv
|
|
|
|
[ -z "$server" ] && server=$new_dhcp_server_identifier
|
|
|
|
[ -z "$server" ] && server=$new_next_server
|
|
|
|
[ -z "$server" ] && server=${new_root_path%%:*}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Look through $options, fix "rw"/"ro", move "lock"/"nolock" to $nfslock
|
|
|
|
munge_nfs_options() {
|
|
|
|
local f="" flags="" nfsrw="ro" OLDIFS="$IFS"
|
|
|
|
IFS=,
|
|
|
|
for f in $options; do
|
|
|
|
case $f in
|
|
|
|
ro|rw) nfsrw=$f ;;
|
|
|
|
lock|nolock) nfslock=$f ;;
|
|
|
|
*) flags=${flags:+$flags,}$f ;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
IFS="$OLDIFS"
|
|
|
|
|
|
|
|
# Override rw/ro if set on cmdline
|
|
|
|
getarg ro >/dev/null && nfsrw=ro
|
|
|
|
getarg rw >/dev/null && nfsrw=rw
|
|
|
|
|
|
|
|
options=$nfsrw${flags:+,$flags}
|
|
|
|
}
|
|
|
|
|
|
|
|
# mount_nfs NFSROOT MNTDIR [NETIF]
|
|
|
|
mount_nfs() {
|
|
|
|
local nfsroot="$1" mntdir="$2" netif="$3"
|
|
|
|
local nfs="" server="" path="" options=""
|
|
|
|
nfs_to_var "$nfsroot" $netif
|
|
|
|
munge_nfs_options
|
|
|
|
if [ "$nfs" = "nfs4" ]; then
|
|
|
|
options=$options${nfslock:+,$nfslock}
|
|
|
|
else
|
|
|
|
# NFSv{2,3} doesn't support using locks as it requires a helper to
|
|
|
|
# transfer the rpcbind state to the new root
|
|
|
|
[ "$nfslock" = "lock" ] \
|
|
|
|
&& warn "Locks unsupported on NFSv{2,3}, using nolock" 1>&2
|
|
|
|
options=$options,nolock
|
|
|
|
fi
|
|
|
|
mount -t $nfs -o$options "$server:$path" "$mntdir"
|
|
|
|
}
|