summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
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
commit6dfb4058af8a59c17aeeb80b567ce521f6ace59b (patch)
tree868744a63ca8b7e03b218d060ae18c889fde5053
parent801f1f62b09c68a42c078b3a619539456b160f45 (diff)
downloadliveslak-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-xliveinit151
-rwxr-xr-xmake_slackware_live.sh37
2 files changed, 186 insertions, 2 deletions
diff --git a/liveinit b/liveinit
index 5b96fe6..008940e 100755
--- a/liveinit
+++ b/liveinit
@@ -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