Bridged network boot

* SYNTAX
bridge=<bridgename>:<ethname>
If bridge without parameters, assume bridge=br0:eth0
* When <ethname> would be configured by network scripts, instead create a bridge named <bridgename> then add <ethname> to that bridge.
* Then $netif becomes <bridgename> instead of <ethname> and all existing scripts process netroot mount via this new $netif instead of <ethname>.
* Include a few test cases in NFS and NBD
master
Warren Togami 2009-07-16 16:58:19 -04:00
parent 44f1ab8285
commit beb097d9f1
8 changed files with 117 additions and 4 deletions

View File

@ -1,4 +1,4 @@
#!/bin/sh
which ip dhclient hostname >/dev/null 2>&1 || exit 1
which ip dhclient hostname brctl >/dev/null 2>&1 || exit 1
exit 255


View File

@ -60,6 +60,14 @@ fi
# $netif reads easier than $1
netif=$1

# bridge this interface?
if [ -e /tmp/bridge.info ]; then
. /tmp/bridge.info
if [ "$netif" = "$ethname" ]; then
netif="$bridgename"
fi
fi

# bail immediately if the interface is already up
# or we don't need the network
[ -f "/tmp/net.$netif.up" ] && exit 0
@ -77,6 +85,15 @@ fi

# XXX need error handling like dhclient-script

# start bridge if necessary
if [ "$netif" = "$bridgename" ] && [ ! -e /tmp/net.$bridgename.up ]; then
ip link set $ethname up
# Create bridge and add eth to bridge
brctl addbr $bridgename
brctl setfd $bridgename 0
brctl addif $bridgename $ethname
fi

# No ip lines default to dhcp
ip=$(getarg ip)
[ -z "$ip" ] && do_dhcp;

View File

@ -1,5 +1,5 @@
#!/bin/bash
dracut_install ip dhclient hostname
dracut_install ip dhclient hostname brctl
# Include wired net drivers, excluding wireless
for modname in $(find "/lib/modules/$kernel/kernel/drivers" -name '*.ko'); do
if nm -uPA $modname | grep -q eth_type_trans; then
@ -15,9 +15,12 @@ inst "$moddir/netroot" "/sbin/netroot"
inst "$moddir/dhclient-script" "/sbin/dhclient-script"
inst "$moddir/dhclient.conf" "/etc/dhclient.conf"
instmods ecb arc4
# bridge modules
instmods bridge stp llc
inst_hook pre-udev 60 "$moddir/net-genrules.sh"
inst_hook cmdline 91 "$moddir/dhcp-root.sh"
inst_hook cmdline 99 "$moddir/parse-ip-opts.sh"
inst_hook cmdline 98 "$moddir/parse-bridge.sh"
inst_hook pre-pivot 10 "$moddir/kill-dhclient.sh"

# TODO ifcfg config style is redhat specific, this should probably

View File

@ -14,6 +14,11 @@ fix_bootif() {

# Write udev rules
{
# bridge: attempt only the defined interface
if [ -e /tmp/bridge.info ]; then
. /tmp/bridge.info
IFACES=$ethname
fi

# BOOTIF says everything, use only that one
BOOTIF=$(getarg 'BOOTIF=')

View File

@ -0,0 +1,53 @@
#!/bin/sh
#
# Format:
# bridge=<bridgename>:<ethname>
#
# bridge without parameters assumes bridge=br0:eth0
#

# return if bridge already parsed
[ -n "$bridgename" ] && return

# Check if bridge parameter is valid
if getarg ip= >/dev/null ; then
if [ -z "$netroot" ] ; then
die "No netboot configured, bridge is invalid"
fi
fi

parsebridge() {
local v=${1}:
set --
while [ -n "$v" ]; do
set -- "$@" "${v%%:*}"
v=${v#*:}
done

unset bridgename ethname
case $# in
0) bridgename=br0; ethname=eth0 ;;
1) die "bridge= requires two parameters" ;;
2) bridgename=$1; ethname=$2 ;;
*) die "bridge= requires two parameters" ;;
esac
}

unset bridgename ethname

# Parse bridge for bridgename and ethname
if getarg bridge >/dev/null; then
# Read bridge= parameters if they exist
bridge="$(getarg bridge=)"
if [ ! "$bridge" = "bridge" ]; then
parsebridge "$(getarg bridge=)"
fi
# Simple default bridge
if [ -z "$bridgename" ]; then
bridgename=br0
ethname=eth0
fi
echo "bridgename=$bridgename" > /tmp/bridge.info
echo "ethname=$ethname" >> /tmp/bridge.info
return
fi

View File

@ -6,11 +6,14 @@
read IFACES < /tmp/net.ifaces

for netif in $IFACES ; do
# bridge?
unset bridge
if [ "$netif" = "$bridgename" ]; then
bridge=yes
fi
cat /sys/class/net/$netif/address > /tmp/net.$netif.hwaddr
echo "# Generated by dracut initrd" > /tmp/net.$netif.ifcfg
echo "DEVICE=$netif" >> /tmp/net.$netif.ifcfg
echo "HWADDR=$(cat /sys/class/net/$netif/address)" >> /tmp/net.$netif.ifcfg
echo "TYPE=Ethernet" >> /tmp/net.$netif.ifcfg
echo "ONBOOT=yes" >> /tmp/net.$netif.ifcfg
if [ -f /tmp/net.$netif.lease ]; then
echo "BOOTPROTO=dhcp" >> /tmp/net.$netif.ifcfg
@ -22,4 +25,23 @@ for netif in $IFACES ; do
echo "NETMASK=$mask" >> /tmp/net.$netif.ifcfg
[ -n "$gw" ] && echo "GATEWAY=$gw" >> /tmp/net.$netif.ifcfg
fi

# bridge needs differente things written to ifcfg
if [ -z "$bridge" ]; then
# standard interface
echo "HWADDR=$(cat /sys/class/net/$netif/address)" >> /tmp/net.$netif.ifcfg
echo "TYPE=Ethernet" >> /tmp/net.$netif.ifcfg
echo "NAME=\"Boot Disk\"" >> /tmp/net.$netif.ifcfg
else
# bridge
echo "TYPE=Bridge" >> /tmp/net.$netif.ifcfg
echo "NAME=\"Boot Disk\"" >> /tmp/net.$netif.ifcfg
# write separate ifcfg file for the raw eth interface
echo "DEVICE=$ethname" >> /tmp/net.$ethname.ifcfg
echo "TYPE=Ethernet" >> /tmp/net.$ethname.ifcfg
echo "ONBOOT=yes" >> /tmp/net.$ethname.ifcfg
echo "HWADDR=$(cat /sys/class/net/$ethname/address)" >> /tmp/net.$ethname.ifcfg
echo "BRIDGE=$netif" >> /tmp/net.$ethname.ifcfg
echo "NAME=$ethname" >> /tmp/net.$ethname.ifcfg
fi
done

View File

@ -125,6 +125,9 @@ test_nfsv3() {
client_test "NFSv3 root=nfs:..." 52:54:00:12:34:04 \
"root=nfs:192.168.50.1:/nfs/client" 192.168.50.1 -wsize=4096 || return 1

client_test "NFSv3 Bridge root=nfs:..." 52:54:00:12:34:04 \
"root=nfs:192.168.50.1:/nfs/client bridge" 192.168.50.1 -wsize=4096 || return 1

client_test "NFSv3 Legacy root=IP:path" 52:54:00:12:34:04 \
"root=192.168.50.1:/nfs/client" 192.168.50.1 -wsize=4096 || return 1

@ -135,6 +138,9 @@ test_nfsv3() {
client_test "NFSv3 root=dhcp DHCP path,options" \
52:54:00:12:34:05 "root=dhcp" 192.168.50.1 wsize=4096 || return 1

client_test "NFSv3 Bridge Customized root=dhcp DHCP path,options" \
52:54:00:12:34:05 "root=dhcp bridge=foobr0:eth0" 192.168.50.1 wsize=4096 || return 1

client_test "NFSv3 root=dhcp DHCP IP:path,options" \
52:54:00:12:34:06 "root=dhcp" 192.168.50.2 wsize=4096 || return 1


View File

@ -106,6 +106,10 @@ test_run() {
"root=nbd:192.168.50.1:2000:ext2:errors=panic" \
ext2 errors=panic || return 1

client_test "NBD Bridge root=nbd:IP:port:fstype:fsopts" 52:54:00:12:34:00 \
"root=nbd:192.168.50.1:2000:ext2:errors=panic bridge" \
ext2 errors=panic || return 1

# There doesn't seem to be a good way to validate the NBD options, so
# just check that we don't screw up the other options

@ -125,6 +129,9 @@ test_run() {
client_test "NBD root=dhcp DHCP root-path nbd:srv:port" 52:54:00:12:34:01 \
"root=dhcp" || return 1

client_test "NBD Bridge root=dhcp DHCP root-path nbd:srv:port" 52:54:00:12:34:01 \
"root=dhcp bridge" || return 1

client_test "NBD root=dhcp DHCP root-path nbd:srv:port:fstype" \
52:54:00:12:34:02 "root=dhcp" ext2 || return 1