From 1b31fc140baef770d498776bdebf9226f178b0dd Mon Sep 17 00:00:00 2001 From: Philippe Seewer Date: Tue, 16 Jun 2009 19:14:51 +0200 Subject: [PATCH] netroot: Add ip= cmdline checker As with other netroot boot arguments ip= lines should be parsed and checked. Having this has the advantage that other cmdline scripts can tell the ip= parser if dhcp or ip=:srv:... is needed, like parse-root.sh (renamed dhcp-fallback) or parse-nfsroot do. The nfs test-suite has one check which uses static ip lines, but the autoconf param is wrong. Fixed this as well. --- modules.d/40network/dhcp-fallback.sh | 23 ------- modules.d/40network/dhcp-root.sh | 20 +++++++ modules.d/40network/install | 3 +- modules.d/40network/parse-ip-opts.sh | 90 ++++++++++++++++++++++++++++ modules.d/95nfs/parse-nfsroot.sh | 2 +- test/TEST-20-NFS/test.sh | 2 +- 6 files changed, 114 insertions(+), 26 deletions(-) delete mode 100755 modules.d/40network/dhcp-fallback.sh create mode 100755 modules.d/40network/dhcp-root.sh create mode 100755 modules.d/40network/parse-ip-opts.sh diff --git a/modules.d/40network/dhcp-fallback.sh b/modules.d/40network/dhcp-fallback.sh deleted file mode 100755 index 78436406..00000000 --- a/modules.d/40network/dhcp-fallback.sh +++ /dev/null @@ -1,23 +0,0 @@ -# We should go last, and default the root if needed - -if [ -z "$root" -a -z "$netroot" ]; then - rootok=1 - root=dhcp - netroot=dhcp -fi - -if [ "$root" = "dhcp" -a -z "$netroot" ]; then - rootok=1 - netroot=dhcp -fi - -if [ "$netroot" = "dhcp" -a -z "$root" ]; then - rootok=1 - root=dhcp -fi - -if [ -n "$NEEDDHCP" ] ; then - rootok=1 - root=dhcp - #Don't overwrite netroot here, as it might contain something useful -fi diff --git a/modules.d/40network/dhcp-root.sh b/modules.d/40network/dhcp-root.sh new file mode 100755 index 00000000..c00ba063 --- /dev/null +++ b/modules.d/40network/dhcp-root.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# Don't continue if root is ok +[ -n "$rootok" ] && return + +# This script is sourced, so root should be set. But let's be paranoid +[ -z "$root" ] && root=$(getarg root=) +[ -z "$netroot" ] && netroot=$(getarg netroot=) + +if [ "$root" = "dhcp" ] || [ "$netroot" = "dhcp" ] ; then + # Tell ip= checker that we need dhcp + NEEDDHCP="1" + + # Done, all good! + rootok=1 + netroot=dhcp + + # Shut up init error check + [ -z "$root" ] && root="dhcp" +fi diff --git a/modules.d/40network/install b/modules.d/40network/install index 2e381e28..cb9359e9 100755 --- a/modules.d/40network/install +++ b/modules.d/40network/install @@ -16,7 +16,8 @@ inst "$moddir/dhclient-script" "/sbin/dhclient-script" inst "$moddir/dhclient.conf" "/etc/dhclient.conf" instmods ecb arc4 inst_rules "$moddir/60-net.rules" -inst_hook cmdline 99 "$moddir/dhcp-fallback.sh" +inst_hook cmdline 91 "$moddir/dhcp-root.sh" +inst_hook cmdline 99 "$moddir/parse-ip-opts.sh" inst_hook pre-pivot 10 "$moddir/kill-dhclient.sh" # TODO ifcfg config style is redhat specific, this should probably diff --git a/modules.d/40network/parse-ip-opts.sh b/modules.d/40network/parse-ip-opts.sh new file mode 100755 index 00000000..df1a071e --- /dev/null +++ b/modules.d/40network/parse-ip-opts.sh @@ -0,0 +1,90 @@ +#!/bin/sh +# +# Format: +# ip=[dhcp|on|any] +# +# ip=:[dhcp|on|any] +# +# ip=::::::[dhcp|on|any|none|off] +# + +# Sadly there's no easy way to split ':' separated lines into variables +ip_to_var() { + local v=${1}: + set -- + while [ -n "$v" ]; do + set -- "$@" "${v%%:*}" + v=${v#*:} + done + + unset ip srv gw mask hostname dev autoconf + case $# in + 0) autoconf="error" ;; + 1) autoconf=$1 ;; + 2) dev=$1; autoconf=$2 ;; + *) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7 ;; + esac +} + +# Warn if defaulting to ip=dhcp +if [ -n "$netroot" ] && [ -z "$(getarg ip=)" ] ; then + warn "No ip= argument(s) for netroot provided, defaulting to DHCP" + return; +fi + +# Check ip= lines +# XXX Would be nice if we could errorcheck ip addresses here as well +[ "$CMDLINE" ] || read CMDLINE < /proc/cmdline +for p in $CMDLINE; do + [ -n "${p%ip=*}" ] && continue + + ip_to_var ${p#ip=} + + # Empty autoconf defaults to 'dhcp' + if [ -z "$autoconf" ] ; then + warn "Empty autoconf values default to dhcp" + autoconf="dhcp" + fi + + # Error checking for autoconf in combination with other values + case $autoconf in + error) die "Error parsing option '$p'";; + bootp|rarp|both) die "Sorry, ip=$autoconf is currenty unsupported";; + none|off) \ + [ -z "$ip" ] && \ + die "For argument '$p'\nValue '$autoconf' without static configuration does not make sense" + [ -z "$mask" ] && \ + die "Sorry, automatic calculation of netmask is not yet supported" + ;; + dhcp|on|any) \ + [ -n "$ip" ] && \ + die "For argument '$p'\nSorry, setting client-ip does not make sense for '$autoconf'" + ;; + *) die "For argument '$p'\nSorry, unknown value '$autoconf'";; + esac + + # We don't like duplicate device configs + if [ -n "$dev" ] ; then + if [ -n "$IFACES" ] ; then + for i in $IFACES ; do + [ "$dev" = "$i" ] && die "For argument '$p'\nDuplication configurations for '$dev'" + done + fi + IFACES="$IFACES $dev" + fi + + # Do we need DHCP? (It's simpler to check for a set ip. Checks above ensure that if + # ip is there, we're static) + [ -n "$NEEDDHCP" ] && [ -z "$ip" ] && DHCPOK="1" + + # Do we need srv OR dhcp? + if [ -n "$DHCPORSERVER" ] ; then + [ -n "$DHCPOK" ] && SRVOK="1" + [ -n "$srv" ] && SRVOK="1" + fi + +done + +[ -n "$NEEDDHCP" ] && [ -z "$DHCPOK" ] && die "Server-ip or dhcp for netboot needed, but current arguments say otherwise" + +[ -n "$DHCPORSERVER" ] && [ -z "$SRVOK" ] && die "Server-ip or dhcp for netboot needed, but current arguments say otherwise" diff --git a/modules.d/95nfs/parse-nfsroot.sh b/modules.d/95nfs/parse-nfsroot.sh index d47be9e7..0a742883 100755 --- a/modules.d/95nfs/parse-nfsroot.sh +++ b/modules.d/95nfs/parse-nfsroot.sh @@ -125,7 +125,7 @@ netroot="$fstype:$server:$path:$options" # If we don't have a server, we need dhcp if [ -z "$server" ] ; then - NEEDDHCP="1" + DHCPORSERVER="1" fi; # Done, all good! diff --git a/test/TEST-20-NFS/test.sh b/test/TEST-20-NFS/test.sh index 7dc3245f..0f1f36c3 100755 --- a/test/TEST-20-NFS/test.sh +++ b/test/TEST-20-NFS/test.sh @@ -164,7 +164,7 @@ test_nfsv3() { client_test "NFSv3 root=nfs nfsroot=/nfs/ip/%s no host name (use IP)" \ 52:54:00:12:34:7f \ "root=nfs nfsroot=/nfs/ip/%s \ - ip=192.168.50.101:192.168.50.1::255.255.255.0::eth0:static" \ + ip=192.168.50.101:192.168.50.1::255.255.255.0::eth0:off" \ 192.168.50.1 -wsize=4096 || return 1 client_test "NFSv3 root=nfs nfsroot=/nfs/client,wsize=4096" \