Dear Colleagues, during our work here at our office, we were trying to deploy newly bought HP BL465C G7 Bladeserver (http://h10010.www1.hp.com/wwpc/us/en/sm/WF05a/3709945-3709945-3328410-241641-3328419-4132949.html) with 10GbE NC551i FlexFabric 2 Ports NICs.
Those NICs are represented by the be2net and be2iscsi kernel drivers. And then came the problem...strangely klibcs ipconfig wasn't able to reliable do dhcp requests inside the initramfs. As the first PXE DHCP/BOOTP request was working and we are using the BOOTIF parameter of pxelinux to catch exactly that interface, we were sure that our DHCP infrastructure is working (we are doing some dhcp relay configs inside our network). So, during the last days I was debugging and debugging without finding any hint why ipconfig is not able to accept the dhcp provided IP address, while we saw the request on the dhcp server. Today I was so frustrated that I thought to myself "when ipconfig is not working, I need some better dhcpclient". I remembered the LTSP project, because they fought with the very same problem some time ago, and checked their repositories for some initramfs udhcpc magic and found it. http://bazaar.launchpad.net/~ltsp-upstream/ltsp/ltsp-trunk/annotate/head:/client/initramfs/hooks/udhcp this is the hook script for copying the udhcpc binary into the initramfs. http://bazaar.launchpad.net/~ltsp-upstream/ltsp/ltsp-trunk/annotate/head:/client/initramfs/scripts/init-premount/udhcp This is the init-premount script from them. As we are not using the standard init stuff from initramfs but the live overlay of it I had to adjust the script to my needs. As explained above, we are using the BOOTIF parameter from pxelinux.0 therefore I didn't play around with all the other ip stuff and came directly to the point. chroot <FAIDIR>/nfsroot/live/filesystem.dir and changed the do_netmount shell function in /usr/share/initramfs-tools/scripts/live: The function now looks like this: do_netmount () { rc=1 modprobe -q af_packet # For DHCP if [ -x /sbin/udevadm ] then # lenny udevadm trigger udevadm settle else # etch udevtrigger udevsettle fi # ipconfig ${DEVICE} | tee /netboot.config if [ -n "${BOOTIF}" ]; then # pxelinux sets BOOTIF to a value based on the mac address of the # network card used to PXE boot, so use this value for DEVICE rather # than a hard-coded device name from initramfs.conf. this facilitates # network booting when machines may have multiple network cards. # pxelinux sets BOOTIF to 01-$mac_address # strip off the leading "01-", which isn't part of the mac # address echo "BootIF ${BOOTIF}" temp_mac=${BOOTIF#*-} # convert to typical mac address format by replacing "-" with ":" bootif_mac="" IFS='-' for x in $temp_mac ; do if [ -z "$bootif_mac" ]; then bootif_mac="$x" else bootif_mac="$bootif_mac:$x" fi done unset IFS # look for devices with matching mac address, and set DEVICE to # appropriate value if match is found. for device in /sys/class/net/* ; do if [ -f "$device/address" ]; then current_mac=$(cat "$device/address") if [ "$bootif_mac" = "$current_mac" ]; then DEVICE=${device##*/} echo "DEVICE FOUND: ${DEVICE}" break fi fi done fi ################################################## # # generate /tmp/dhcp-script.sh # ################################################## echo '#!/bin/sh [ "$1" = "bound" ] || exit echo "# this file contains....." > /tmp/dhcp-info.conf for var in interface ip siaddr sname boot_file subnet timezone router \ timesvr namesvr dns logsvr cookiesvr lprsvr hostname bootsize domain \ swapsvr rootpath ipttl mtu broadcast ntpsrv wins lease dhcptype serverid \ message tftp bootfile; do eval value=\"\$$var\" if [ -n "$value" ]; then echo $var="\"$value\"" >> /tmp/dhcp-info.conf fi done' > /tmp/dhcp-script.sh chmod +x /tmp/dhcp-script.sh ip link set $DEVICE up echo "Sleeping 5 seconds to reall have an up interface" sleep 5 ##################################### # # Do UDHCPC # ##################################### while [ -z "$configured" ]; do if udhcpc -n -s /tmp/dhcp-script.sh -i $DEVICE > /dev/null 2>&1; then configured="true" break fi done #################################### # # source in dhcp-info.conf # ################################### . /tmp/dhcp-info.conf ip address add $ip/$(subnet_to_cidr $subnet) broadcast ${broadcast:-+} dev $DEVICE for i in $router do ip route add default via $i dev $DEVICE done echo "$DEVICE configuret at $ip:$tftp:$router:$subnet:$hostname" read dns0 dns1 rest_dns <<EOF $dns EOF read router0 rest_routers <<EOF $router EOF echo "DEVICE='$DEVICE' IPV4ADDR='$ip' IPV4BROADCAST='$broadcast' IPV4NETMASK='$subnet' IPV4GATEWAY='$router0' IPV4DNS0='$dns0' IPV4DNS1='$dns1' HOSTNAME='$hostname' DNSDOMAIN='$domain' NISDOMAIN='$domain' ROOTSERVER='$siaddr' ROOTPATH='$rootpath' filename='$bootfile' DNS_SERVER='$dns' SEARCH_DOMAIN='$domain' NTPSVR='$ntpsrv' TIMESVR='$timesvr' TIMEZONE='$timezone' LOGSVR='$logsvr'" > /tmp/net-$DEVICE.conf # source relevant ipconfig output OLDHOSTNAME=${HOSTNAME} . /tmp/net-${DEVICE}.conf [ -z ${HOSTNAME} ] && HOSTNAME=${OLDHOSTNAME} export HOSTNAME # Check if we have a network device at all if ! ls /sys/class/net/eth0 > /dev/null 2>&1 && \ ! ls /sys/class/net/wlan0 > /dev/null 2>&1 && \ ! ls /sys/class/net/ath0 > /dev/null 2>&1 && \ ! ls /sys/class/net/ra0 > /dev/null 2>&1 then panic "No supported network device found, maybe a non-mainline driver is required." fi if [ "${NFSROOT}" = "auto" ] then NFSROOT=${ROOTSERVER}:${ROOTPATH} fi if ( [ -n "${FETCH}" ] || [ -n "${HTTPFS}" ] || [ -n "${FTPFS}" ] ) && do_httpmount then rc=0 return ${rc} fi if [ "${NFSROOT#*:}" = "${NFSROOT}" ] && [ "$NETBOOT" != "cifs" ] then NFSROOT=${ROOTSERVER}:${NFSROOT} fi log_begin_msg "Trying netboot from ${NFSROOT}" if [ "${NETBOOT}" != "nfs" ] && do_cifsmount then rc=0 elif do_nfsmount then NETBOOT="nfs" export NETBOOT rc=0 fi log_end_msg return ${rc} } for this to work you need at last another change to the "live" script. Inside the function Arguments() at top of the "live" script you need to add the BOOTIF parameter like this: BOOTIF=*) BOOTIF="${ARGUMENT#BOOTIF=}" export BOOTIF ;; After updateing the initramfs inside the chroot and copying after that the initrd.img for the used install boot kernel into the tftpd root, my problem was solved. I know that this workaround doesn't look pretty and doesn't solve all problems when you don't use the IPAPPEND parameter of pxelinux. So, I'm going to do some more adjusting of the LTSP udhcpc script and adjust it to all our needs. udhcpc does not fail on vmwares with standard hardware and does not fail on machines with be2net/be2iscsi nics. Tests with bnx2 and bnx2x nics were also successful. I'm thinking, that udhcpc is a better solution for dhcp requests inside (live) initramfs and we should try to go that way. I don't know what it needs to start the discussion with initramfs upstream (or the linux plumbers) but we could also create a separate fai initramfs overlay (just like the live one). What do you think? Regards, \sh -- Stephan '\sh' Adig SysAdmin / Ubuntu Developer xmpp: s...@sourcecode.de