network: prepare network configuration engine for udev-based nfsroot

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.
master
David Dillow 2009-05-22 22:43:32 -04:00 committed by Harald Hoyer
parent df44688f3e
commit 7e9919b927
5 changed files with 182 additions and 57 deletions

View File

@ -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.

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
}
[ -e /hostname.set ] || {
[ -n "$hostname" ] && mknod /hostname.set p && run hostname $hostname
}
}

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
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
set |grep -E '^new_[a-z_]+=' |while read line; do
echo "${line%%=*}='${line#*=}'">>/net.$interface.dhcpopts
done
>/net.$interface.up ;;
>/net.$netif.up
echo online > /sys/class/net/$netif/uevent ;;
*) ;;
esac

trap - EXIT
exit 0

View File

@ -1,36 +1,112 @@
#!/bin/sh

PATH=$PATH:/sbin:/usr/sbin

. /lib/dracut-lib

getarg netdebug && {
exec >/ifup.$1.$$.out
exec 2>>/ifup.$1.$$.out
set -x
}

netif=$1

# bail immediatly if the interface is already up
[ -f "/net.$1.up" ] && exit 0
[ -f "/net.$netif.up" ] && exit 0

# loopback is always handled the same way
[ "$1" = "lo" ] && {
/sbin/ip link set lo up
/sbin/ip addr add 127.0.0.1/8 dev lo
[ "$netif" = "lo" ] && {
ip link set lo up
ip addr add 127.0.0.1/8 dev lo
>/net.$netif.up
exit 0
}

# XXX need error handling like dhclient-script

die() {
echo $netif: "$@" 1>&2
exit 1
}

do_static() {
[ -n "$ip" ] || die "static: need IP address"
[ -n "$mask" ] || {
net=${ip%%.*}
mask=255.0.0.0
[ $net -ge 128 ] && mask=255.255.0.0
[ $net -ge 192 ] && mask=255.255.255.0
}
ip addr add $ip/$mask dev $netif || die "static: setting IP $ip/$mask"
[ -n "$gw" ] && {
ip route add default via $gw dev $netif ||
die "static: setting default route via $gw"
}
ip link set $netif up
[ -e /hostname.set ] || {
[ -n "$hostname" ] && mknod /hostname.set p 2>/dev/null &&
hostname $hostname
}
[ -n "$srv" ] &&
echo "new_dhcp_server_identifier=$srv" > /net.$netif.dhcpopts

>/net.$netif.up
echo online > /sys/class/net/$netif/uevent
}

do_dhcp() {
reqs=subnet-mask,broadcast-address,routers,domain-name
reqs=${reqs},domain-name-servers,domain-search
reqs=${reqs},host-name,root-path,interface-mtu

for i in ip srv gw mask hostname; do
eval '[ "$'$i'" ] && echo '$i'="$'$i'"'
done > /net.$netif.override
[ -n "$ip" ] && echo bcast= >> /net.$netif.override

# /sbin/dhclient-script will mark the netif up and generate the online
# event for nfsroot
# XXX add -V vendor class and option parsing per kernel
dhclient -1 -q -R ${reqs} -pf /dhclient.$netif.pid $netif
}

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=off ;;
1) autoconf=$1 ;;
2) dev=$1; autoconf=$2 ;;
*) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7
case $autoconf in
''|none|off) [ -n "$ip" ] && autoconf=static ;;
esac
esac
[ -n "$dev" ] || dev=$netif
[ -n "$autoconf" ] || autoconf=off
}

# spin through the kernel command line, looking for ip= lines
for p in $(cat /proc/cmdline); do
[ "${p%%=*}" = "ip" ] || continue
ip=${p#ip=}
case $ip in
none|off) exit 0;; # we were told to not configure anything
dhcp|on|any) >/net.$1.dhcp; exit 0;;
bootp|rarp|both) exit 0;; #dunno how to do this
*) echo ${ip} | \
(IFS=':' read client server gw netmask hostname device autoconf
if [ -z "$device" -o "$device" = "$1" ]; then
case $autoconf in
dhcp|on|any) >/net.$1.dhcp ;;
none|off|'') # do some basic configuration
/sbin/ip link set $1 up
/sbin/ip addr add $client/$netmask dev $1
[ "$gw" ] && /sbin/ip route add default via $gw dev $1
>/net.$1.up ;;
esac
fi
) ;;
*) continue;;
[ -n "${p%ip=*}" ] && continue
ip_to_var ${p#ip=}

# If this option isn't directed at our interface, skip it
[ "$dev" = "$netif" ] || continue

case $autoconf in
static) do_static ;;
dhcp|on|any) do_dhcp ;;
bootp|rarp|both) die "autoconfig type $autoconf is not supported" ;;
''|none|off) ;;
esac
break
done
exit 0

View File

@ -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"

View File

@ -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

View File

@ -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