[PATCH 2/9] 95nfs: add nfs-lib.sh

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



nfs-lib.sh contains a bunch of functions used to parse NFS "url"s of
various types, pull nfs information out of dhcp info, and actually
perform nfs mounts sanely.

Signed-off-by: Will Woods <wwoods@xxxxxxxxxx>
---
 modules.d/95nfs/module-setup.sh |    1 +
 modules.d/95nfs/nfs-lib.sh      |  139 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+), 0 deletions(-)
 create mode 100755 modules.d/95nfs/nfs-lib.sh

diff --git a/modules.d/95nfs/module-setup.sh b/modules.d/95nfs/module-setup.sh
index 0e921ff..19d618c 100755
--- a/modules.d/95nfs/module-setup.sh
+++ b/modules.d/95nfs/module-setup.sh
@@ -60,6 +60,7 @@ install() {
     inst_hook pre-udev 99 "$moddir/nfs-start-rpc.sh"
     inst_hook pre-pivot 99 "$moddir/nfsroot-cleanup.sh"
     inst "$moddir/nfsroot" "/sbin/nfsroot"
+    inst "$moddir/nfs-lib.sh" "/lib/nfs-lib.sh"
     mkdir -m 0755 -p "$initdir/var/lib/nfs/rpc_pipefs"
     mkdir -m 0755 -p "$initdir/var/lib/rpcbind"
     mkdir -m 0755 -p "$initdir/var/lib/nfs/statd/sm"
diff --git a/modules.d/95nfs/nfs-lib.sh b/modules.d/95nfs/nfs-lib.sh
new file mode 100755
index 0000000..4f3d184
--- /dev/null
+++ b/modules.d/95nfs/nfs-lib.sh
@@ -0,0 +1,139 @@
+#!/bin/sh
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=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_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
+    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##*:/}"
+}
+
+# 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 || return
+    done
+    [ -n "$new_root_path" ] && nfsroot_to_var "$nfs:$new_root_path"
+    [ -z "$path" ] && [ "$(getarg root=)" == "/dev/nfs" ] && path=/tftpboot/%s
+    [ -z "$server" ] && server=$new_dhcp_server_identifier
+    [ -z "$server" ] && server=$new_dhcp_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
+}
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux