summaryrefslogtreecommitdiffstats
path: root/liveinit
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 /liveinit
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
Diffstat (limited to '')
-rwxr-xr-xliveinit151
1 files changed, 150 insertions, 1 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