summaryrefslogtreecommitdiffstats
path: root/liveinit
diff options
context:
space:
mode:
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