diff options
author | Eric Hameleers <alien@slackware.com> | 2016-04-13 00:34:31 +0200 |
---|---|---|
committer | Eric Hameleers <alien@slackware.com> | 2016-04-13 00:34:31 +0200 |
commit | 6dfb4058af8a59c17aeeb80b567ce521f6ace59b (patch) | |
tree | 868744a63ca8b7e03b218d060ae18c889fde5053 | |
parent | 801f1f62b09c68a42c078b3a619539456b160f45 (diff) | |
download | liveslak-6dfb4058af8a59c17aeeb80b567ce521f6ace59b.tar.gz liveslak-6dfb4058af8a59c17aeeb80b567ce521f6ace59b.tar.xz |
Add NFS root support.
It is now possible to PXE-boot the Slackware Live Edition.
Extract the content of the ISO to (for instance) a new directory
called 'slackware-live' below your TFTP server's /tftproot directory
and then add lines like this to your pxelinux.cfg/default file:
label liveslak
kernel slackware-live/boot/generic
append initrd=slackware-live/boot/initrd.img load_ramdisk=1 prompt_ramdisk=0 rw printk.time=0 kbd=us tz=Europe/Amsterdam locale=us_EN.utf8 nfsroot=192.168.0.1:/tftpboot/slackware-live hostname=pxelive
Two new boot parameters have been added to support a NFS root:
* nfsroot => mandatory parameter defines the IP address of the NFS server
and the path to the extracted content of Slackware Live Edition.
* nic => parameter defining the driver for the network card (optional
and usually not needed because UDEV will figure out the driver for you),
the interface name (optional),
the IP configuration method (static IP or DHCP),
and in case of a static IP, the required parameters ipaddress, netmask
and an optional gateway.
Note that the 'nic' parameter is optional if you have a DHCP server in
your LAN: Slackware Live will figure out what the interface name is.
Syntax of these parameters:
nfsroot=ip.ad.dr.ess:/path/to/liveslak
nic=<driver>:<interface>:<dhcp|static>[:ipaddr:netmask[:gateway]]
Example use of these parameters:
nfsroot=192.168.1.1:/tftproot/slackware-live
nic=auto:eth0:static:10.0.0.21:24:
nic=:eth1:static:192.168.1.6:255.255.255.248:192.168.1.1
-rwxr-xr-x | liveinit | 151 | ||||
-rwxr-xr-x | make_slackware_live.sh | 37 |
2 files changed, 186 insertions, 2 deletions
@@ -69,6 +69,10 @@ BLACKLIST="" # default in X.Org is to enable it: GLAMORACCEL=1 +# NFS root support: +INTERFACE="" +NFSHOST="" + INITRD=$(cat /initrd-name) WAIT=$(cat /wait-for-root) KEYMAP=$(cat /keymap) @@ -141,9 +145,18 @@ for ARG in $(cat /proc/cmdline); do maxloops=*) MAXLOOPS=$(echo $ARG | cut -f2 -d=) ;; + nfsroot=*) + # nfsroot=192.168.0.1:/path/to/liveslak + NFSHOST=$(echo $ARG | cut -f2 -d= |cut -f1 -d:) + NFSPATH=$(echo $ARG | cut -f2 -d= |cut -f2 -d:) + ;; nga) GLAMORACCEL=0 ;; + nic=*) + # nic=<driver>:<interface>:<dhcp|static>[:ipaddr:netmask[:gateway]] + ENET=$(echo $ARG | cut -f2 -d=) + ;; noload=*) NOLOAD=$(echo $ARG | cut -f2 -d=) ;; @@ -214,6 +227,10 @@ rescue() { if [ -x /sbin/udevd -a -x /sbin/udevadm ]; then /sbin/udevd --daemon --resolve-names=never /sbin/udevadm trigger --subsystem-match=block --action=add + if [ -n "$NFSHOST" ]; then + # We also need network devices if NFS root is requested: + /sbin/udevadm trigger --type=devices --action=add + fi /sbin/udevadm settle --timeout=10 else [ "$DEVTMPFS" != "1" ] && mdev -s @@ -282,6 +299,108 @@ if [ "$RESCUE" = "" ]; then ## Support functions ## + cidr_cvt() { + # Function to convert the netmask from CIDR format to dot notation. + # Number of args to shift, 255..255, first non-255 byte, zeroes + set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 + [ $1 -gt 1 ] && shift $1 || shift + echo ${1-0}.${2-0}.${3-0}.${4-0} + } + + setnet() { + # Find and configure the network interface for NFS root support. + # Assume nothing about the method of network configuration: + ENET_MODE="ask" + # Max wait time for DHCP client to configure an interface: + MAXDHCP=10 + + echo "${MARKER}: Configuring network interface for NFS mount." + + # Does the commandline have NIC information for us? + # Format is 'nic=driver:interface:<dhcp|static>:ip:mask:gw' + if [ -n "$ENET" ]; then + DRIVER=$(echo $ENET |cut -f1 -d:) + INTERFACE=$(echo $ENET |cut -f2 -d:) + ENET_MODE=$(echo $ENET |cut -f3 -d:) + if [ "$ENET_MODE" = "static" ]; then + IPADDR=$(echo $ENET |cut -f4 -d:) + NETMASK=$(echo $ENET |cut -f5 -d:) + # We allow for CIDR notation of the netmask (0 < NETMASK < 25): + if [ "$(echo $NETMASK |tr -cd '\.')" != "..." ]; then + NETMASK=$(cidr_cvt $NETMASK) + fi + # Determine BROADCAST: + eval $(ipcalc -b $IPADDR $NETMASK) + # Not mandatory: + GATEWAY=$(echo $ENET | cut -f6 -d:) + fi + fi + + # If no interface is present the cmdline should have provided a driver: + if [ $(cat /proc/net/dev |grep ':' |sed -e "s/^ *//" |cut -f1 -d: |grep -v lo |wc -l) -eq 0 ]; then + if [ "x${DRIVER}" != "x" ]; then + # This takes silent care of 'DRIVER=auto' as well... + modprobe ${DRIVER} 1>/dev/null 2>/dev/null + fi + fi + + # Let's determine the interface: + if [ "x$INTERFACE" = "x" -o "$INTERFACE" = "auto" ]; then + # Cmdline did not provide a nic or it's "auto" to let dhcpcd find out: + for EDEV in $(cat /proc/net/dev |grep ':' |sed -e "s/^ *//" |cut -f1 -d: |grep -v lo) ; do + if grep -q $(echo ${EDEV}: |cut -f 1 -d :): /proc/net/wireless ; then + continue # skip wireless interfaces + fi + # If this configures an interface, we're done with dhcpcd afterwards: + /sbin/dhcpcd -L -p -t $MAXDHCP $EDEV & + done + unset EDEV + # Wait at most MAXDHCP seconds for a DHCP-configured interface to appear: + for ITER in $(seq 0 $MAXDHCP); do + if $(ip -f inet -o addr show | grep -v " lo " 1>/dev/null 2>/dev/null) + then + # Found one! + break + fi + sleep 1 + done + # What interface did dhcpcd configure? + INTERFACE="" + for EDEV in $(cat /proc/net/dev |grep ':' |sed -e "s/^ *//" |cut -f1 -d: |grep -v lo); do + if [ -s /run/dhcpcd/dhcpcd-${EDEV}.pid ]; then + INTERFACE="${EDEV}" + break + fi + done + unset EDEV + fi + + if [ "x$INTERFACE" = "x" ]; then + # Failed to find a configured interface... desperate measure: + echo "${MARKER}: Failed to find network interface... trouble ahead." + INTERFACE="eth0" + fi + + # We know our INTERFACE, so let's configure it: + if [ "$ENET_MODE" = "ask" -o "$ENET_MODE" = "dhcp" ]; then + # Invoke dhcpcd only if it was not called yet: + if [ ! -s /run/dhcpcd/dhcpcd-${INTERFACE}.pid ]; then + /sbin/dhcpcd -L -p -t $MAXDHCP $INTERFACE + fi + else + # Kill dhcpcd if we used it to find a statically configured interface: + if [ -s /run/dhcpcd/dhcpcd-${INTERFACE}.pid ]; then + /sbin/dhcpcd -k $INTERFACE + fi + # Static IP address requires IPADDRESS, NETMASK, NETMASK at a minimum: + ifconfig $INTERFACE $IPADDR netmask $NETMASK broadcast $BROADCAST + if [ -n "$GATEWAY" ]; then + route add default gw $GATEWAY metric 1 + fi + fi + + } # End setnet() + find_loop() { # The losetup of busybox is different from the real losetup - watch out! lodev=$(losetup -f) @@ -363,7 +482,16 @@ if [ "$RESCUE" = "" ]; then # Find the Slackware Live media. # TIP: Increase WAIT to give USB devices a chance to be seen by the kernel. mkdir /mnt/media - if [ -z "$LIVEMEDIA" ]; then + if [ -n "$NFSHOST" ]; then + # NFS root. First configure our network interface: + setnet + # Mount the NFS share and hope for the best: + mount -t nfs -o nolock,vers=3 $NFSHOST:$NFSPATH /mnt/media + LIVEALL="$NFSHOST:$NFSPATH" + LIVEMEDIA="$LIVEALL" + # No writing on NFS exports, overlayfs does not support it: + VIRGIN=1 + elif [ -z "$LIVEMEDIA" ]; then # LIVEMEDIA not specified on the boot commandline using "livemedia=" # Filter out the block devices, only look at partitions at first: LIVEALL=$(blkid |grep LABEL="\"$MEDIALABEL\"" |cut -d: -f1 |grep "[0-9]$") @@ -704,6 +832,27 @@ EOPW sed -i -e "s/^\(127.0.0.1\t*\)@DARKSTAR@.*/\1${LIVE_HOSTNAME}.example.net ${LIVE_HOSTNAME}/" /mnt/overlay/etc/hosts fi + if [ -n "$NFSHOST" -a -s /run/dhcpcd/dhcpcd-${INTERFACE}.pid ]; then + # Ensure that dhcpcd will find its configuration: + mount --bind /var/lib/dhcpcd /mnt/overlay/var/lib/dhcpcd + mkdir -p /mnt/overlay/run/dhcpcd + mount --bind /run/dhcpcd /mnt/overlay/run/dhcpcd + + # Disable NetworkManager: + chmod -x /mnt/overlay/etc/rc.d/rc.networkmanager + + # De-configure rc.inet1: + cat <<EOT > /mnt/overlay/etc/rc.d/rc.inet1.conf +IFNAME[0]="$INTERFACE" +IPADDR[0]="" +NETMASK[0]="" +USE_DHCP[0]="" +DHCP_HOSTNAME[0]="" +GATEWAY="" +DEBUG_ETH_UP="no" +EOT + fi + # Disable glamor 2D acceleration (QEMU needs this): if [ $GLAMORACCEL -eq 0 ]; then cat <<EOT > /mnt/overlay/etc/X11/xorg.conf.d/20-noglamor.conf diff --git a/make_slackware_live.sh b/make_slackware_live.sh index f3f82d7..6fe3b34 100755 --- a/make_slackware_live.sh +++ b/make_slackware_live.sh @@ -36,7 +36,7 @@ # ----------------------------------------------------------------------------- # Version of the Live OS generator: -VERSION="0.7.2" +VERSION="0.7.3" # Directory where our live tools are stored: LIVE_TOOLDIR=${LIVE_TOOLDIR:-"$(cd $(dirname $0); pwd)"} @@ -65,6 +65,9 @@ BOOTLOADSIZE=${BOOTLOADSIZE:-4} # Therefore we disable 32bit EFI by default. Enable at your own peril: EFI32=${EFI32:-"NO"} +# Include support for NFS root (PXE boot), will increase size of the initrd: +NFSROOTSUP=${NFSROOTSUP:-"YES"} + # Timestamp: THEDATE=$(date +%Y%m%d) @@ -163,6 +166,15 @@ SEQ_CIN="tagfile:a,ap,d,e,f,k,l,n,t,tcl,x,xap,xfce,y pkglist:slackextra,cinnamon # Lots of HID modules added to support keyboard input for LUKS password entry: KMODS=${KMODS:-"squashfs:overlay:loop:xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:usb-storage:hid:usbhid:hid-generic:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:jbd:mbcache:ext3:ext4:isofs:fat:nls_cp437:nls_iso8859-1:msdos:vfat"} +# Firmware for wired network cards required for NFS root support: +NETFIRMWARE="3com acenic adaptec bnx tigon e100 sun kaweth tr_smctr cxgb3" + +# Network kernel modules to include for NFS root support: +NETMODS="kernel/drivers/net" + +# Network kernel modules to exclude from above list: +NETEXCL="appletalk arcnet bonding can dummy.ko hamradio hippi ifb.ko irda macvlan.ko macvtap.ko pcmcia sb1000.ko team tokenring tun.ko usb veth.ko wan wimax wireless xen-netback.ko" + # # --------------------------------------------------------------------------- # @@ -1558,6 +1570,29 @@ cat $LIVE_TOOLDIR/liveinit | sed \ cat /dev/null > ${LIVE_ROOTDIR}/boot/initrd-tree/luksdev # We do not add openobex to the initrd and don't want to see irrelevant errors: rm ${LIVE_ROOTDIR}/boot/initrd-tree/lib/udev/rules.d/*openobex*rules 2>${DBGOUT} || true +if [ "$NFSROOTSUP" = "YES" ]; then + # Add dhcpcd for NFS root support: + DHCPD_PKG=$(find ${DEF_SL_PKGROOT}/../ -name "dhcpcd-*.t?z" |head -1) + tar -C ${LIVE_ROOTDIR}/boot/initrd-tree/ -xf ${DHCPD_PKG} \ + var/lib/dhcpcd lib/dhcpcd sbin/dhcpcd usr/lib${DIRSUFFIX}/dhcpcd \ + etc/dhcpcd.conf.new + mv ${LIVE_ROOTDIR}/boot/initrd-tree/etc/dhcpcd.conf{.new,} + # Add just the right kernel network modules by pruning unneeded stuff: + KMODS_PKG=$(find ${DEF_SL_PKGROOT}/../ -name "kernel-modules-*$(echo $KVER |tr - _)*.t?z" |head -1) + tar -C ${LIVE_ROOTDIR}/boot/initrd-tree/ -xf ${KMODS_PKG} \ + lib/modules/${KVER}/${NETMODS} + for KNETRM in ${NETEXCL} ; do + find ${LIVE_ROOTDIR}/boot/initrd-tree/lib/modules/${KVER}/${NETMODS} \ + -name $KNETRM -depth -exec rm -rf {} \; + done + # We added extra modules to the initrd, so we run depmod again: + chroot ${LIVE_ROOTDIR}/boot/initrd-tree /sbin/depmod $KVER + # Add the firmware for network cards that need them: + KFW_PKG=$(find ${DEF_SL_PKGROOT}/../ -name "kernel-firmware-*.t?z" |head -1) + tar tf ${KFW_PKG} |grep -E "($(echo $NETFIRMWARE |tr ' ' '|'))" \ + |xargs tar -C ${LIVE_ROOTDIR}/boot/initrd-tree/ -xf ${KFW_PKG} \ + 2>/dev/null || true +fi # Wrap up the initrd.img again: chroot ${LIVE_ROOTDIR} /sbin/mkinitrd 1>/dev/null 2>${DBGOUT} rm -rf ${LIVE_ROOTDIR}/boot/initrd-tree |