Skip to contentSkip to conversation

WIP: NFS root mount from udev rules

RFC PATCH New David Dillow 1 participant 6 messages May 23, 2009 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

cover WIP: NFS root mount from udev rules

This is my current patch queue for mount the NFS root via the udev rules. It worked well when I stopped activity on it in mid-April, but I've not tested it after porting to today's HEAD.

The first two patches are bug fixes, though Victor posted a different fix to the default config file issue in his cleanup series.

Mainly, I'm looking to see what you guys think of the direction.

Thanks for any comments you care to share!

David Dillow (5):
dracut-funtions: fix 'instmods =XXX'
dracut: fix fallback to default configuration file
lib: create a library for useful shell functions
network: prepare network configuration engine for udev-based nfsroot
nfsroot: mount NFS root from udev rules

 dracut                                 |    7 +-
 dracut-functions                       |    2 +-
 modules.d/40network/dhclient-script    |   98 +++++++++++++++----
 modules.d/40network/ifup               |  124 +++++++++++++++++++-----
 modules.d/40network/install            |    3 +-
 modules.d/40network/kill-dhclient.sh   |    5 +-
 modules.d/40network/run-dhclient.sh    |    9 --
 modules.d/40nfsroot/60-nfsroot.rules   |    1 +
 modules.d/40nfsroot/check              |    5 +
 modules.d/40nfsroot/install            |   27 +++++
 modules.d/40nfsroot/nfsroot            |  125 ++++++++++++++++++++++++
 modules.d/40nfsroot/nfsroot-cleanup.sh |    9 ++
 modules.d/99base/dracut-lib            |   16 +++
 modules.d/99base/init                  |   12 +--
 modules.d/99base/install               |    1 +
 15 files changed, 374 insertions(+), 70 deletions(-)
 delete mode 100755 modules.d/40network/run-dhclient.sh
 create mode 100644 modules.d/40nfsroot/60-nfsroot.rules
 create mode 100755 modules.d/40nfsroot/check
 create mode 100755 modules.d/40nfsroot/install
 create mode 100755 modules.d/40nfsroot/nfsroot
 create mode 100755 modules.d/40nfsroot/nfsroot-cleanup.sh
 create mode 100644 modules.d/99base/dracut-lib

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

A message that is not in the archive (sent off-list or not yet received): cover.1243053563.git.dave-i1Mk8JYDVaaSihdK6806/[email protected]

#2 lore raw

RFC PATCH 1/5 dracut-funtions: fix 'instmods =modname'

Move srcmods definition into the function, as $kernel isn't defined yet when dracut-functions is sourced from dracut.

---
 dracut-functions |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
dracut-functions +1 -1
index 2beaef2..36f1a96 100755
@@ -202,9 +202,9 @@ dracut_install() {
 }
 
 # install modules, and handle installing all their dependencies as well.
-srcmods="/lib/modules/$kernel/"
 instmods() {
     local mod mpargs modpath modname cmd
+    local srcmods="/lib/modules/$kernel/"
     while (($# > 0)); do
 	mod=${1%.ko}
 	case $mod in
Signature · 6 lines
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#3 lore raw

RFC PATCH 2/5 dracut: fix fallback to default configuration file

In reply to a message not in the archive

Need to do the fallback in a list rather than a subshell, or we never actually set $conffile.

---
 dracut |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
dracut +1 -1
index 0170fbb..0cf00c6 100755
@@ -57,7 +57,7 @@ while (($# > 0)); do
     shift
 done
 
-[[ -f $conffile ]] || ( [[ -f /etc/dracut.conf ]] && conffile="/etc/dracut.conf" )
+[[ -f $conffile ]] || { [[ -f /etc/dracut.conf ]] && conffile="/etc/dracut.conf" }
 [[ -f $conffile ]] && . "$conffile"
 [[ $dracutmodules_l ]] && dracutmodules=$dracutmodules_l
 [[ $omit_dracutmodules_l ]] && omit_dracutmodules=$omit_dracutmodules_l
Signature · 6 lines
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#4 lore raw

RFC PATCH 3/5 lib: create a library for useful shell functions

In reply to a message not in the archive

There are several snippits of shell code that are useful to multiple scripts. Start by moving getarg() into the library.

---
 modules.d/99base/dracut-lib |   16 ++++++++++++++++
 modules.d/99base/init       |   12 ++----------
 modules.d/99base/install    |    1 +
 3 files changed, 19 insertions(+), 10 deletions(-)
modules.d/99base/dracut-lib new file +16 -0
new file mode 100644
index 0000000..1f31933
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Licensed under the GPLv2
+#
+# Copyright 2008, Red Hat, Inc.
+# Jeremy Katz <[email protected]>
+
+getarg() {
+    local o line
+    [ "$CMDLINE" ] || read CMDLINE </proc/cmdline;
+    for o in $CMDLINE; do
+	[ "$o" = "$1" ] && return 0
+	[ "${o%%=*}" = "${1%=}" ] && { echo ${o#*=}; return 0; }
+    done
+    return 1
+}
modules.d/99base/init +2 -10
index ac6a2d8..05cc4b7 100755
@@ -14,15 +14,6 @@ emergency_shell()
     sh -i
 }
 
-getarg() {
-    local o line
-    for o in $CMDLINE; do
-	[ "$o" = "$1" ] && return 0
-	[ "${o%%=*}" = "${1%=}" ] && { echo ${o#*=}; return 0; }
-    done
-    return 1
-}
-
 source_all() {
     local f
     [ "$1" ] && [  -d "/$1" ] || return
@@ -35,6 +26,8 @@ NEWROOT="/sysroot"
 
 trap "emergency_shell" 0
 
+. /lib/dracut-lib
+
 mknod /dev/null c 1 3
 
 # mount some important things
@@ -42,7 +35,6 @@ mount -t proc /proc /proc >/dev/null 2>&1
 mount -t sysfs /sys /sys >/dev/null 2>&1
 mount -t tmpfs -omode=0755 udev /dev >/dev/null 2>&1
 
-read CMDLINE </proc/cmdline;
 getarg ramfsdebug && set -x
 # Make some basic devices first, let udev handle the rest
 mknod /dev/null c 1 3
modules.d/99base/install +1 -0
index 00436ae..ce1e2f9 100755
@@ -9,4 +9,5 @@ if [ ! -x "$moddir/switch_root" ]; then
     exit 1
 fi
 inst "$moddir/switch_root" "/sbin/switch_root"
+inst "$moddir/dracut-lib" "/lib/dracut-lib"
 inst_hook pre-pivot 50 "$moddir/selinux-loadpolicy.sh"
Signature · 6 lines
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#5 lore raw

RFC PATCH 4/5 network: prepare network configuration engine for udev-based nfsroot

In reply to a message not in the archive

This changes the network config to run dhclient from within udev, and allows multiple dhclients to run at once. It also sets the hostname and adds a kernel command line option 'netdebug' to help debug network issues.

This an RFC patch, as I've not tested it since porting to the current dracut (it worked in HEAD as of April, though).

---
 modules.d/40network/dhclient-script  |   98 ++++++++++++++++----
 modules.d/40network/ifup             |  124 +++++++++++++++++++++-----
 modules.d/40network/install          |    3 +-
 modules.d/40network/kill-dhclient.sh |    5 +-
 modules.d/40network/run-dhclient.sh  |    9 --
 5 files changed, 182 insertions(+), 57 deletions(-)
modules.d/40network/dhclient-script +78 -20
index 895ed1b..7689e04 100755
@@ -1,27 +1,85 @@
-#!/bin/sh
+#!/bin/sh -e
 # very simple dhclient-script.  All it cares about is bringing the interface
 # up, and it does not even try to do anything else.
 
-case $reason in
-    PREINIT) /sbin/ip link set "$interface" up ;;
-    BOUND) ipopts="$new_ip_address"
-     	[ "$new_interface_mtu" ] && ip link set $interface mtu $new_interface_mtu
-	[ "$new_subnet_mask" ] && ipopts="$ipopts/$new_subnet_mask"
-	[ "$new_broadcast_address" ] && ipopts="$ipopts broadcast $new_broadcast_address"
-	/sbin/ip addr add $ipopts dev $interface
-	[ "$new_routers" ] && /sbin/ip route add default via ${new_routers%%,*} dev $interface
-	[ "$new_domain_name" ] && echo "domain $new_domain_name" > /etc/resolv.conf
-	if [ "$new_domain_search" ]; then
-	    echo "search $new_domain_search" |sed 's/,//g' >> /etc/resolv.conf
-	elif [ "$new_domain_name" ]; then
-	    echo "search $new_domain_name" >> /etc/resolv.conf
-	fi
-	for s in $new_domain_name_servers; do
-	    echo "nameserver $s" >> /etc/resolv.conf
+LOG=/dhclient.$$.log
+ERR=/network.$$.err
+PATH=$PATH:/sbin:/usr/sbin
+
+. /lib/dracut-lib
+
+getarg netdebug && {
+    exec >/dhclient.$interface.$$.out
+    exec 2>>/dhclient.$interface.$$.out
+    set -x
+}
+
+log_err() {
+    # avoid the need for cat on the image
+    echo "On $netif, the following command:" > $ERR
+    echo "    " "$CMD" >> $ERR
+    echo "had errors:" >> $ERR
+    while read line; do echo "     $line"; done < $LOG >> $ERR
+}
+
+# Catch unlikely initial errors
+trap 'echo Errors preparing to configure $netif > $ERR; exit 0' EXIT
+
+netif=$interface
+ip=$new_ip_address
+mtu=$new_interface_mtu
+mask=$new_subnet_mask
+bcast=$new_broadcast_address
+gw=${new_routers%%,*}
+domain=$new_domain_name
+search=$new_domain_search
+namesrv=$new_domain_name_servers
+hostname=$new_host_name
+
+[ -f /net.$interface.override ] && . /net.$interface.override
+
+# save the offending command and let udev move on if we have an error
+trap 'log_err; exit 0' EXIT
+
+run() {
+    CMD="$@"
+    "$@" >> $LOG 2>&1
+}
+
+setup_interface() {
+    [ -n "$mtu" ] && {
+	run ip link set $netif down
+	run ip link set $netif mtu $mtu
+	run ip link set $netif up
+    }
+
+    run ip addr add $ip${mask:+/$mask} ${bcast:+broadcast $bcast} dev $netif
+    [ -n "$gw" ] && run ip route add default via $gw
+    [ -n "${search}${domain}" -a -n "$namesrv" ] && {
+	echo search $search $domain > /etc/resolv.conf
+	for s in $namesrv; do
+	    echo nameserver $s >> /etc/resolv.conf
 	done
-	set |grep -E '^new_[a-z_]+=' |while read line; do
-	    echo "${line%%=*}='${line#*=}'">>/net.$interface.dhcpopts
+    }
+    [ -e /hostname.set ] || {
+	[ -n "$hostname" ] && mknod /hostname.set p && run hostname $hostname
+    }
+}
+
+case $reason in
+    PREINIT)
+	run /sbin/ip link set $netif up
+	;;
+    BOUND)
+	setup_interface 
+	set | while read line; do
+	    [ "${line#new_}" = "$line" ] && continue
+	    echo "$line" >>/net.$netif.dhcpopts
 	done
-	>/net.$interface.up ;;
+	>/net.$netif.up
+	echo online > /sys/class/net/$netif/uevent ;;
     *) ;;
 esac
+
+trap - EXIT
+exit 0
modules.d/40network/ifup +100 -24

136 lines not on this page · raw message

modules.d/40network/install +1 -2
index c0c13fc..7a13348 100755
@@ -1,10 +1,9 @@
 #!/bin/bash
-dracut_install ip dhclient grep
+dracut_install ip dhclient hostname
 instmods ${modules:-=net}
 inst "$moddir/ifup" "/sbin/ifup"
 inst "$moddir/dhclient-script" "/sbin/dhclient-script"
 instmods =networking ecb arc4
 inst_rules "$moddir/60-net.rules"
 inst_hook pre-pivot 10 "$moddir/kill-dhclient.sh"
-inst_hook pre-mount 70 "$moddir/run-dhclient.sh"
 mkdir -p "${initdir}/var/run"
modules.d/40network/kill-dhclient.sh +3 -2
index 70deda6..d1d15f4 100755
@@ -1,4 +1,5 @@
 #!/bin/sh
 
-pid=$(pidof dhclient)
-[ -n "$pid" ] && kill $pid
+for f in /dhclient.*.pid; do
+    [ "$f" != "/dhclient.*.pid" ] && kill $(cat $f)
+done
modules.d/40network/run-dhclient.sh deleted +0 -9
deleted file mode 100755
index bc32883..0000000
@@ -1,9 +0,0 @@
-#!/bin/sh
-for i in /net.*.dhcp; do
-    [ "$i" = '/net.*.dhcp' ] && break
-    dev=${i#/net.}; dev=${dev%.dhcp}
-    [ -f "/net.$dev.up" ] && continue
-    dhclient  -R 'subnet-mask,broadcast-address,time-offset,routers,domain-name,domain-name-servers,host-name,nis-domain,nis-servers,ntp-servers,root-path' -1 -q $dev &
-done
-wait
-    
Signature · 6 lines
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#6 lore raw

RFC PATCH 5/5 nfsroot: mount NFS root from udev rules

In reply to a message not in the archive

Work-in-progress to mount NFS root from udev, using the DHCP options and allowing an override from the kernel command line. Supports NFSv4 w/locking and NFSv2/v3 with nolock.

This is just an RFC patch, you'll note all the XXX markings where I've been thinking about how to best do things. In addition, we really want to retry DHCP and NFS mounting in a loop, in case the servers are down or overloaded like when booting a full diskless cluster.

---
 dracut                                 |    5 +-
 modules.d/40nfsroot/60-nfsroot.rules   |    1 +
 modules.d/40nfsroot/check              |    5 +
 modules.d/40nfsroot/install            |   27 +++++
 modules.d/40nfsroot/nfsroot            |  125 ++++++++++++++++++++++++
 modules.d/40nfsroot/nfsroot-cleanup.sh |    9 ++
 6 files changed, 171 insertions(+), 1 deletions(-)
dracut +4 -1
index 0cf00c6..4c06588 100755
@@ -99,10 +99,13 @@ hookdirs="pre-udev pre-mount pre-pivot mount emergency"
 readonly initdir=$(mktemp -d -t initramfs.XXXXXX)
 trap 'rm -rf "$initdir"' 0 # clean up after ourselves no matter how we die.
 
+# Need to be able to have non-root users read stuff (rpcbind etc)
+chmod 755 "$initdir"
+
 export initdir hookdirs dsrc dracutmodules modules debug beverbose
 
 # Create some directory structure first
-for d in bin sbin usr/bin usr/sbin usr/lib etc proc sys sysroot dev/pts; do 
+for d in bin sbin usr/bin usr/sbin usr/lib etc proc sys sysroot dev/pts var/run; do 
     mkdir -p "$initdir/$d"; 
 done
 
modules.d/40nfsroot/60-nfsroot.rules new file +1 -0
new file mode 100644
index 0000000..99a2acf
@@ -0,0 +1 @@
+ACTION=="online", SUBSYSTEM=="net", RUN+="/sbin/nfsroot $env{INTERFACE}"
modules.d/40nfsroot/check new file +5 -0
new file mode 100755
index 0000000..b7378c3
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+# This is not a module that should be selected when we try to
+# autoconfigure the initrd 
+exit 1
modules.d/40nfsroot/install new file +27 -0
new file mode 100755
index 0000000..965c63c
@@ -0,0 +1,27 @@
+#!/bin/sh
+dracut_install rpcbind rpc.statd mount.nfs mount.nfs4
+dracut_install /etc/netconfig /etc/passwd /etc/services
+
+# XXX debug stuff
+dracut_install rpcinfo ping strace dmesg nc free df
+
+dracut_install rpc.idmapd /etc/idmapd.conf
+
+instmods nfs
+inst_rules "$moddir/60-nfsroot.rules"
+inst_hook pre-pivot 70 "$moddir/nfsroot-cleanup.sh"
+inst "$moddir/nfsroot" "/sbin/nfsroot"
+mkdir -p "$initdir/var/lib/nfs/rpc_pipefs"
+mkdir -p "$initdir/var/lib/rpcbind"
+mkdir -p "$initdir/var/lib/nfs/statd/sm"
+
+# XXX debug
+mkdir -p "$initdir/mnt"
+
+# Rather than copy the passwd file in, just set a user for rpcbind
+# We'll save the state and restart the daemon from the root anyway
+#echo "rpc:x:32:32:Rpcbind:/var/lib/rpcbind:/bin/false" >> "$initdir/etc/passwd"
+
+# rpc user needs to be able to write to this directory to save the warmstart
+# file
+chmod 777 "$initdir/var/lib/rpcbind"
modules.d/40nfsroot/nfsroot new file +125 -0

125 lines not on this page · raw message

modules.d/40nfsroot/nfsroot-cleanup.sh new file +9 -0
new file mode 100755
index 0000000..7bdec0a
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+pid=$(pidof rpc.statd)
+[ -n "$pid" ] && kill $pid
+
+pid=$(pidof rpcbind)
+[ -n "$pid" ] && kill $pid
+
+mount --move /var/lib/nfs/rpc_pipefs $NEWROOT/var/lib/nfs/rpc_pipefs
Signature · 6 lines
1.6.0.6

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