diff options
-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 |