Add netboot infrastructure: custom initramfs hooks, build scripts, iPXE configuration
This commit is contained in:
147
initramfs/scripts/netboot
Executable file
147
initramfs/scripts/netboot
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Import standard initramfs functions
|
||||
. /scripts/functions
|
||||
|
||||
export PATH=/usr/bin:/usr/sbin:/bin:/sbin
|
||||
MOUNTPOINT=/root
|
||||
TMPFS_MOUNT=/mnt
|
||||
|
||||
# Parse kernel command line for HTTP root
|
||||
parse_cmdline() {
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case $x in
|
||||
root=http://*)
|
||||
export ROOT_URL="${x#root=}" ;;
|
||||
rootfstype=*)
|
||||
export ROOTFSTYPE="${x#rootfstype=}" ;;
|
||||
overlayroot=*)
|
||||
export OVERLAYROOT="${x#overlayroot=}" ;;
|
||||
ip=*)
|
||||
export BOOTIP="${x#ip=}" ;;
|
||||
*)
|
||||
: ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
mountroot() {
|
||||
rc=1
|
||||
parse_cmdline
|
||||
|
||||
if test -z "${ROOT_URL}"; then
|
||||
log_failure_msg "No root URL defined (root=http://... not found)"
|
||||
return ${rc}
|
||||
fi
|
||||
|
||||
# Configure networking before attempting downloads
|
||||
log_begin_msg "Configuring network"
|
||||
modprobe af_packet || log_warning_msg "af_packet load failed"
|
||||
|
||||
# Load RTL8125 driver (already in module list but explicit load for debugging)
|
||||
modprobe r8125 || log_warning_msg "r8125 driver load failed, may use generic driver"
|
||||
|
||||
configure_networking
|
||||
udevadm trigger
|
||||
timeout 30 udevadm settle || log_warning_msg "udevadm settle timed out"
|
||||
export DEVICE
|
||||
log_end_msg
|
||||
|
||||
# Validate networking is up
|
||||
INTERFACE_UP=0
|
||||
for iface in $(ip link show | grep "^[0-9]" | awk -F: '{print $2}' | tr -d ' '); do
|
||||
if ip addr show "$iface" | grep -q "inet "; then
|
||||
INTERFACE_UP=1
|
||||
log_begin_msg "Interface $iface has IP address"
|
||||
ip addr show "$iface" | grep "inet " | awk '{print $2}'
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $INTERFACE_UP -eq 0 ]; then
|
||||
log_failure_msg "No network interface obtained an IP address"
|
||||
return ${rc}
|
||||
fi
|
||||
|
||||
# Extract filename from URL
|
||||
FILE_NAME=$(basename "${ROOT_URL}")
|
||||
FILE_PATH="/${FILE_NAME}"
|
||||
|
||||
# Download the root filesystem with retries and timeouts
|
||||
log_begin_msg "Downloading root filesystem from ${ROOT_URL}"
|
||||
if wget --timeout=30 --tries=3 --waitretry=5 \
|
||||
--progress=dot:mega \
|
||||
"${ROOT_URL}" -O "${FILE_PATH}"; then
|
||||
log_end_msg
|
||||
else
|
||||
log_failure_msg "Failed to download from ${ROOT_URL} after retries"
|
||||
rm -f "${FILE_PATH}"
|
||||
return ${rc}
|
||||
fi
|
||||
|
||||
# Verify the downloaded file is a valid SquashFS
|
||||
if ! file "${FILE_PATH}" | grep -q "Squash"; then
|
||||
log_failure_msg "Downloaded file is not a valid SquashFS image"
|
||||
rm -f "${FILE_PATH}"
|
||||
return ${rc}
|
||||
fi
|
||||
|
||||
# Handle SquashFS images with overlay
|
||||
if echo "${FILE_NAME}" | grep -q squashfs; then
|
||||
log_begin_msg "Setting up SquashFS with overlay"
|
||||
|
||||
# Mount read-only SquashFS
|
||||
if ! mount -t squashfs "${FILE_PATH}" "${MOUNTPOINT}" -o ro; then
|
||||
log_failure_msg "Failed to mount SquashFS at ${MOUNTPOINT}"
|
||||
rm -f "${FILE_PATH}"
|
||||
return ${rc}
|
||||
fi
|
||||
log_begin_msg "SquashFS mounted at ${MOUNTPOINT}"
|
||||
log_end_msg
|
||||
|
||||
# Setup overlay if requested
|
||||
if [ -n "${OVERLAYROOT}" ]; then
|
||||
log_begin_msg "Mounting ${OVERLAYROOT} for overlay"
|
||||
|
||||
# Create tmpfs for upper and work directories
|
||||
if ! mount -o size=2G -t "${OVERLAYROOT}" tmpfs_overlay "${TMPFS_MOUNT}"; then
|
||||
log_failure_msg "Failed to mount tmpfs for overlay"
|
||||
umount "${MOUNTPOINT}"
|
||||
rm -f "${FILE_PATH}"
|
||||
return ${rc}
|
||||
fi
|
||||
|
||||
# Create overlay structure
|
||||
mkdir -p "${TMPFS_MOUNT}/upper" "${TMPFS_MOUNT}/work"
|
||||
|
||||
# Mount overlay combining read-only lower + writable upper
|
||||
if ! mount -t overlay \
|
||||
-o "lowerdir=${MOUNTPOINT},upperdir=${TMPFS_MOUNT}/upper,workdir=${TMPFS_MOUNT}/work" \
|
||||
overlay_root "${MOUNTPOINT}"; then
|
||||
log_failure_msg "Failed to mount overlay filesystem"
|
||||
umount "${TMPFS_MOUNT}"
|
||||
umount "${MOUNTPOINT}"
|
||||
rm -f "${FILE_PATH}"
|
||||
return ${rc}
|
||||
fi
|
||||
|
||||
log_end_msg
|
||||
log_begin_msg "Overlay mounted successfully"
|
||||
log_end_msg
|
||||
|
||||
# Clean up downloaded image as it's now mounted
|
||||
rm -f "${FILE_PATH}"
|
||||
rc=0
|
||||
else
|
||||
# Direct SquashFS mount without overlay
|
||||
log_begin_msg "Mounted SquashFS without overlay"
|
||||
log_end_msg
|
||||
rc=0
|
||||
fi
|
||||
else
|
||||
log_failure_msg "Unknown filesystem type: ${FILE_NAME}"
|
||||
rm -f "${FILE_PATH}"
|
||||
fi
|
||||
|
||||
return ${rc}
|
||||
}
|
||||
Reference in New Issue
Block a user