diff --git a/dracut.8 b/dracut.8 index 1abc6900..d82e437d 100644 --- a/dracut.8 +++ b/dracut.8 @@ -236,22 +236,22 @@ only activate the raid sets with the given UUID .SS Network .TP -.BR ip= {dhcp|on|any|auto6} +.BR ip= {dhcp|on|any|dhcp6|auto6} dhcp|on|any: get ip from dhcp server from all interfaces. If root=dhcp, loop sequentially through all interfaces (eth0, eth1, ...) and use the first with a valid DHCP root-path. -auto6: do ipv6 autoconfiguration +auto6: do IPv6 autoconfiguration .TP -.BR ip= :{dhcp|on|any|auto6} -dhcp|on|any: get ip from dhcp server on a specific interface +.BR ip= :{dhcp|on|any|dhcp6|auto6} +dhcp|on|any|dhcp6: get ip from dhcp server on a specific interface -auto6: do ipv6 autoconfiguration +auto6: do IPv6 autoconfiguration .TP .ad l .BR ip= "\%\::[]\::\::\::\::\::{none|off}" .ad -explicit network configuration +explicit network configuration. If you want do define a IPv6 address, put it in brackets (e.g. [2001:DB8::1]). .TP .BR ifname= : Assign network device name (ie eth0) to the NIC with MAC . @@ -277,7 +277,7 @@ NFS options can be appended with the prefix ":" or "," and are seperated by ",". .TP .BR root= "nfs4:[:][:]" .TP -.BR root= dhcp +.BR root= dhcp|dhcp6 root=dhcp alone directs initrd to look at the DHCP root-path where NFS options can be specified. root-path=:[,] diff --git a/modules.d/40network/dhcp-root.sh b/modules.d/40network/dhcp-root.sh index 8e51ed88..644b5ef0 100755 --- a/modules.d/40network/dhcp-root.sh +++ b/modules.d/40network/dhcp-root.sh @@ -7,13 +7,15 @@ [ -z "$root" ] && root=$(getarg root=) [ -z "$netroot" ] && netroot=$(getarg netroot=) -if [ "$root" = "dhcp" ] || [ "$netroot" = "dhcp" ] ; then +if [ "$root" = "dhcp" ] || [ "$root" = "dhcp6" ] || [ "$netroot" = "dhcp" ] ; then # Tell ip= checker that we need dhcp NEEDDHCP="1" # Done, all good! rootok=1 - netroot=dhcp + if [ "$netroot" != "dhcp" ] ; then + netroot=$root + fi # Shut up init error check [ -z "$root" ] && root="dhcp" diff --git a/modules.d/40network/ifup b/modules.d/40network/ifup index 419c2ca6..e2237efe 100755 --- a/modules.d/40network/ifup +++ b/modules.d/40network/ifup @@ -3,45 +3,75 @@ # We don't need to check for ip= errors here, that is handled by the # cmdline parser script # +PATH=$PATH:/sbin:/usr/sbin -# 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 -} +. /lib/dracut-lib.sh # Run dhclient do_dhcp() { # /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 -cf /etc/dhclient.conf -pf /tmp/dhclient.$netif.pid -lf /tmp/dhclient.$netif.lease $netif + dhclient "$@" -1 -q -cf /etc/dhclient.conf -pf /tmp/dhclient.$netif.pid -lf /tmp/dhclient.$netif.lease $netif +} + +load_ipv6() { + modprobe ipv6 + i=0 + while [ ! -d /proc/sys/net/ipv6 ]; do + i=$(($i+1)) + [ $i -gt 10 ] && break + sleep 0.1 + done +} + +do_ipv6auto() { + load_ipv6 + { + echo 0 > /proc/sys/net/ipv6/conf/$netif/forwarding + echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_ra + echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_redirects + echo ip link set $netif up + echo wait_for_if_up $netif + } > /tmp/net.$netif.up + + [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname + + namesrv=$(getargs nameserver) + if [ -n "$namesrv" ] ; then + for s in $namesrv; do + echo nameserver $s + done + fi >> /tmp/net.$netif.resolv.conf + + + echo online > /sys/class/net/$netif/uevent + /sbin/initqueue --onetime --name netroot-$netif /sbin/netroot $netif } # Handle static ip configuration do_static() { + strstr $ip '*:*:*' && load_ipv6 + { echo ip link set $netif up echo wait_for_if_up $netif - echo ip addr flush dev $netif + # do not flush addr for ipv6 + strstr $ip '*:*:*' || \ + echo ip addr flush dev $netif echo ip addr add $ip/$mask dev $netif } > /tmp/net.$netif.up [ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname + namesrv=$(getargs nameserver) + if [ -n "$namesrv" ] ; then + for s in $namesrv; do + echo nameserver $s + done + fi >> /tmp/net.$netif.resolv.conf + echo online > /sys/class/net/$netif/uevent /sbin/initqueue --onetime --name netroot-$netif /sbin/netroot $netif } @@ -99,7 +129,14 @@ fi # No ip lines default to dhcp ip=$(getarg ip) -[ -z "$ip" ] && do_dhcp; + +if [ -z "$ip" ]; then + if [ "$netroot" = "dhcp6" ]; then + do_dhcp -6 + else + do_dhcp -4 + fi +fi # Specific configuration, spin through the kernel command line # looking for ip= lines @@ -115,9 +152,16 @@ for p in $(getargs ip=); do done > /tmp/net.$netif.override case $autoconf in - dhcp|on|any) do_dhcp ;; - *) do_static ;; + dhcp|on|any) + do_dhcp -4 ;; + dhcp6) + do_dhcp -6 ;; + auto6) + do_ipv6auto ;; + *) + do_static ;; esac break done + exit 0 diff --git a/modules.d/40network/install b/modules.d/40network/install index 8421af93..398d4e42 100755 --- a/modules.d/40network/install +++ b/modules.d/40network/install @@ -11,3 +11,18 @@ inst_hook cmdline 99 "$moddir/parse-ip-opts.sh" inst_hook cmdline 98 "$moddir/parse-bridge.sh" inst_hook cmdline 99 "$moddir/parse-ifname.sh" inst_hook pre-pivot 10 "$moddir/kill-dhclient.sh" + +if ldd $(which sh) | grep -q lib64; then + LIBDIR="/lib64" +else + LIBDIR="/lib" +fi + +ARCH=$(uname -m) + +for dir in /usr/$LIBDIR/tls/$ARCH/ /usr/$LIBDIR/tls/ /usr/$LIBDIR/$ARCH/ /usr/$LIBDIR/ /$LIBDIR/; do + for i in $(ls $dir/libnss_dns.so.* $dir/libnss_mdns4_minimal.so.* 2>/dev/null); do + dracut_install $i + done +done + diff --git a/modules.d/40network/installkernel b/modules.d/40network/installkernel index eb88ecd5..514902d6 100755 --- a/modules.d/40network/installkernel +++ b/modules.d/40network/installkernel @@ -14,3 +14,4 @@ instmods $(filter_kernel_modules net_module_test) instmods ecb arc4 # bridge modules instmods bridge stp llc +instmods ipv6 diff --git a/modules.d/40network/netroot b/modules.d/40network/netroot index f1a98df4..6a24d418 100755 --- a/modules.d/40network/netroot +++ b/modules.d/40network/netroot @@ -31,7 +31,7 @@ netif=$1 # Figure out the handler for root=dhcp by recalling all netroot cmdline # handlers -if [ "$netroot" = "dhcp" ] ; then +if [ "$netroot" = "dhcp" ] || [ "$netroot" = "dhcp6" ] ; then # Unset root so we can check later unset root diff --git a/modules.d/40network/parse-ip-opts.sh b/modules.d/40network/parse-ip-opts.sh index 8db9fb5f..327ba5e0 100755 --- a/modules.d/40network/parse-ip-opts.sh +++ b/modules.d/40network/parse-ip-opts.sh @@ -12,23 +12,7 @@ # routing,dns,dhcp-options,etc. # -# 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 -} +. /lib/dracut-lib.sh # Check if ip= lines should be used if getarg ip= >/dev/null ; then diff --git a/modules.d/45ifcfg/write-ifcfg.sh b/modules.d/45ifcfg/write-ifcfg.sh index f75c94fd..f5989ef0 100644 --- a/modules.d/45ifcfg/write-ifcfg.sh +++ b/modules.d/45ifcfg/write-ifcfg.sh @@ -15,39 +15,49 @@ for netif in $IFACES ; do bridge=yes fi cat /sys/class/net/$netif/address > /tmp/net.$netif.hwaddr - echo "# Generated by dracut initrd" > /tmp/ifcfg/ifcfg-$netif - echo "DEVICE=$netif" >> /tmp/ifcfg/ifcfg-$netif - echo "ONBOOT=yes" >> /tmp/ifcfg/ifcfg-$netif - echo "NETBOOT=yes" >> /tmp/ifcfg/ifcfg-$netif - if [ -f /tmp/net.$netif.lease ]; then - echo "BOOTPROTO=dhcp" >> /tmp/ifcfg/ifcfg-$netif - else - echo "BOOTPROTO=none" >> /tmp/ifcfg/ifcfg-$netif + { + echo "# Generated by dracut initrd" + echo "DEVICE=$netif" + echo "ONBOOT=yes" + echo "NETBOOT=yes" + if [ -f /tmp/net.$netif.lease ]; then + strstr "$ip" '*:*:*' && + echo "DHCPV6C=yes" + echo "BOOTPROTO=dhcp" + else + echo "BOOTPROTO=none" # If we've booted with static ip= lines, the override file is there - . /tmp/net.$netif.override - echo "IPADDR=$ip" >> /tmp/ifcfg/ifcfg-$netif - echo "NETMASK=$mask" >> /tmp/ifcfg/ifcfg-$netif - [ -n "$gw" ] && echo "GATEWAY=$gw" >> /tmp/ifcfg/ifcfg-$netif - fi + . /tmp/net.$netif.override + echo "IPADDR=$ip" + echo "NETMASK=$mask" + [ -n "$gw" ] && echo "GATEWAY=$gw" + fi + } > /tmp/ifcfg/ifcfg-$netif # bridge needs different things written to ifcfg if [ -z "$bridge" ]; then # standard interface - echo "HWADDR=$(cat /sys/class/net/$netif/address)" >> /tmp/ifcfg/ifcfg-$netif - echo "TYPE=Ethernet" >> /tmp/ifcfg/ifcfg-$netif - echo "NAME=\"Boot Disk\"" >> /tmp/ifcfg/ifcfg-$netif + { + echo "HWADDR=$(cat /sys/class/net/$netif/address)" + echo "TYPE=Ethernet" + echo "NAME=\"Boot Disk\"" + } >> /tmp/ifcfg/ifcfg-$netif else # bridge - echo "TYPE=Bridge" >> /tmp/ifcfg/ifcfg-$netif - echo "NAME=\"Boot Disk\"" >> /tmp/ifcfg/ifcfg-$netif + { + echo "TYPE=Bridge" + echo "NAME=\"Boot Disk\"" + } >> /tmp/ifcfg/ifcfg-$netif # write separate ifcfg file for the raw eth interface - echo "DEVICE=$ethname" >> /tmp/ifcfg/ifcfg-$ethname - echo "TYPE=Ethernet" >> /tmp/ifcfg/ifcfg-$ethname - echo "ONBOOT=yes" >> /tmp/ifcfg/ifcfg-$ethname - echo "NETBOOT=yes" >> /tmp/ifcfg/ifcfg-$ethname - echo "HWADDR=$(cat /sys/class/net/$ethname/address)" >> /tmp/ifcfg/ifcfg-$ethname - echo "BRIDGE=$netif" >> /tmp/ifcfg/ifcfg-$ethname - echo "NAME=$ethname" >> /tmp/ifcfg/ifcfg-$ethname + { + echo "DEVICE=$ethname" + echo "TYPE=Ethernet" + echo "ONBOOT=yes" + echo "NETBOOT=yes" + echo "HWADDR=$(cat /sys/class/net/$ethname/address)" + echo "BRIDGE=$netif" + echo "NAME=$ethname" + } >> /tmp/ifcfg/ifcfg-$ethname fi done diff --git a/modules.d/95debug/install b/modules.d/95debug/install index cd8c48c9..b9ddee45 100755 --- a/modules.d/95debug/install +++ b/modules.d/95debug/install @@ -1,3 +1,3 @@ #!/bin/bash dracut_install -o ps grep more cat rm strace free showmount -dracut_install -o ping netstat rpcinfo vi scp +dracut_install -o ping netstat rpcinfo vi scp ping6 ssh diff --git a/modules.d/95iscsi/iscsiroot b/modules.d/95iscsi/iscsiroot index 7679a151..308faa48 100755 --- a/modules.d/95iscsi/iscsiroot +++ b/modules.d/95iscsi/iscsiroot @@ -88,15 +88,31 @@ if [ $# -gt 1 ]; then fi fi fi -IFS=: -set $iroot + +IFS="$OLDIFS" + +local v=${iroot}: +local i +set -- +while [ -n "$v" ]; do + if [ "${v#\[*:*:*\]:}" != "$v" ]; then + # handle IPv6 address + i="${v%%\]:*}" + i="${i##\[}" + set -- "$@" "$i" + v=${v#\[$i\]:} + else + set -- "$@" "${v%%:*}" + v=${v#*:} + fi +done iscsi_target_ip=$1; shift iscsi_protocol=$1; shift # ignored iscsi_target_port=$1; shift iscsi_lun=$1; shift +IFS=: iscsi_target_name=$* -IFS="$OLDIFS" - +IFS=$OLDIFS # XXX is this needed? getarg ro && iscsirw=ro getarg rw && iscsirw=rw diff --git a/modules.d/95nfs/nfsroot b/modules.d/95nfs/nfsroot index 4d86bc87..39d5b0c3 100755 --- a/modules.d/95nfs/nfsroot +++ b/modules.d/95nfs/nfsroot @@ -1,43 +1,5 @@ #!/bin/sh -# Copy from parse-nfsroot.sh -root_to_var() { - local v=${1}: - set -- - while [ -n "$v" ]; do - set -- "$@" "${v%%:*}" - v=${v#*:} - done - - unset nfs server path options - - # Ugly: Can't -z test $path after the case, since it might be allowed - # to be empty for root=nfs - nfs=$1 - case $# in - 0|1);; - 2) path=$2;; - 3) - # This is ultra ugly. But we can't decide in which position path - # sits without checking if the string starts with '/' - case $2 in - /*) path=$2; options=$3;; - *) server=$2; path=$3;; - esac - ;; - *) server=$2; path=$3; options=$4; - esac - - # 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 -} - . /lib/dracut-lib.sh PATH=$PATH:/sbin:/usr/sbin @@ -63,7 +25,7 @@ case "${root%%:*}" in *) return;; esac -root_to_var $root +nfsroot_to_var $root #Load other data that might provide info [ -f /tmp/net.$netif.override ] && . /tmp/net.$netif.override @@ -71,7 +33,7 @@ root_to_var $root #Empty path means try dhcp root-path, this is ok here since parse-nfsroot.sh #already takes care of nfs:... formatted root-path -[ -z "$path" ] && root_to_var $nfs:$new_root_path +[ -z "$path" ] && nfsroot_to_var $nfs:$new_root_path #Empty path defaults to "/tftpboot/%s" only in nfsroot.txt legacy mode [ -z "$path" ] && [ "$(getarg root=)" = "/dev/nfs" ] && path="/tftpboot/%s" diff --git a/modules.d/95nfs/parse-nfsroot.sh b/modules.d/95nfs/parse-nfsroot.sh index 6300351f..bcf3465e 100755 --- a/modules.d/95nfs/parse-nfsroot.sh +++ b/modules.d/95nfs/parse-nfsroot.sh @@ -23,43 +23,7 @@ # NFSv3 is used. # -# Sadly there's no easy way to split ':' separated lines into variables -netroot_to_var() { - local v=${1}: - set -- - while [ -n "$v" ]; do - set -- "$@" "${v%%:*}" - v=${v#*:} - done - - unset nfs server path options - - nfs=$1 - # Ugly: Can't -z test #path after the case, since it might be allowed - # to be empty for root=nfs - case $# in - 0|1);; - 2) path=${2:-error};; - 3) - # This is ultra ugly. But we can't decide in which position path - # sits without checking if the string starts with '/' - case $2 in - /*) path=$2; options=$3;; - *) server=$2; path=${3:-error};; - esac - ;; - *) server=$2; path=${3:-error}; options=$4; - esac - - # 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 -} +. /lib/dracut-lib.sh #Don't continue if root is ok [ -n "$rootok" ] && return @@ -105,7 +69,7 @@ case "${netroot%%:*}" in esac # Check required arguments -netroot_to_var $netroot +nfsroot_to_var $netroot [ "$path" = "error" ] && die "Argument nfsroot must contain a valid path!" # Set fstype, might help somewhere diff --git a/modules.d/99base/dracut-lib.sh b/modules.d/99base/dracut-lib.sh index 5b2b2c1a..100219e6 100644 --- a/modules.d/99base/dracut-lib.sh +++ b/modules.d/99base/dracut-lib.sh @@ -1,3 +1,9 @@ + +# returns OK if $1 contains $2 +strstr() { + [ "${1#*$2*}" != "$1" ] +} + getarg() { local o line if [ -z "$CMDLINE" ]; then @@ -50,6 +56,7 @@ setdebug() { [ "$RDDEBUG" = "yes" ] && set -x } +setdebug source_all() { local f @@ -171,3 +178,65 @@ wait_for_if_up() { done return 1 } + +# root=nfs:[:][:] +# root=nfs4:[:][:] +nfsroot_to_var() { + # strip nfs[4]: + local arg="$@:" + nfs="${arg%%:*}" + arg="${arg##$nfs:}" + # check for server + local OLDIFS="$IFS" + + # 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 +} + +ip_to_var() { + local v=${1}: + local i + set -- + while [ -n "$v" ]; do + if [ "${v#\[*:*:*\]:}" != "$v" ]; then + # handle IPv6 address + i="${v%%\]:*}" + i="${i##\[}" + set -- "$@" "$i" + v=${v#\[$i\]:} + else + set -- "$@" "${v%%:*}" + v=${v#*:} + fi + 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 +} +