Fix netboot: hardcode config values, simplify boot chain

- Hardcode ROOT_URL and OVERLAYROOT in netboot script
- Remove cmdline parsing that was failing silently
- Simplify boot.ipxe to chain to netboot.ipxe
- Add rebuild-initramfs.sh helper script

Resolves kernel panic caused by cmdline parsing issues.
This commit is contained in:
2026-02-05 01:16:41 +01:00
parent a927b69aad
commit 258d1ecc60
3 changed files with 117 additions and 200 deletions

View File

@@ -1,207 +1,85 @@
#!/bin/sh
# Netboot HTTP root mounting - sourced by initramfs init (functions already loaded)
# Netboot HTTP root mounting - HARDCODED VALUES - no cmdline parsing
export PATH=/usr/bin:/usr/sbin:/bin:/sbin
# HARDCODED CONFIGURATION
ROOT_URL="http://192.168.100.1:8800/filesystem.squashfs"
OVERLAYROOT="tmpfs"
MOUNTPOINT=/root
SQUASHFS_MOUNT=/mnt/squashfs
OVERLAY_TMPFS=/mnt/overlay
# Hook functions for initramfs-tools boot script integration
netboot_top()
{
if [ "${netboot_top_used}" != "yes" ]; then
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/netboot-top"
run_scripts /scripts/netboot-top
[ "$quiet" != "y" ] && log_end_msg
fi
netboot_top_used=yes
# Debug logging to console
log() {
echo "$@" > /dev/console 2>&1
}
netboot_premount()
{
if [ "${netboot_premount_used}" != "yes" ]; then
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/netboot-premount"
run_scripts /scripts/netboot-premount
[ "$quiet" != "y" ] && log_end_msg
fi
netboot_premount_used=yes
}
netboot_bottom()
{
if [ "${netboot_premount_used}" = "yes" ] || [ "${netboot_top_used}" = "yes" ]; then
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/netboot-bottom"
run_scripts /scripts/netboot-bottom
[ "$quiet" != "y" ] && log_end_msg
fi
netboot_premount_used=no
netboot_top_used=no
}
# 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
}
# Minimal hook functions
netboot_top() { :; }
netboot_premount() { :; }
netboot_bottom() { :; }
mount_top() { :; }
mount_premount() { :; }
mount_bottom() { :; }
mountroot() {
rc=1
log "NETBOOT: ========================================"
log "NETBOOT: mountroot() HARDCODED VERSION"
log "NETBOOT: ROOT_URL=${ROOT_URL}"
log "NETBOOT: ========================================"
# Run hook scripts
netboot_top
netboot_premount
# Load network module
/sbin/modprobe af_packet
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"
# Wait for udev
wait_for_udev 10
# Configure networking via DHCP
log "NETBOOT: Calling configure_networking..."
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
# Check we got an IP
log "NETBOOT: Checking for IP address..."
if ! ip addr show | grep -q "inet "; then
log "NETBOOT: FATAL - no IP address"
return 1
fi
log "NETBOOT: Network is up"
if [ $INTERFACE_UP -eq 0 ]; then
log_failure_msg "No network interface obtained an IP address"
return ${rc}
# Download squashfs
log "NETBOOT: Downloading ${ROOT_URL}..."
if ! wget -O /filesystem.squashfs "${ROOT_URL}"; then
log "NETBOOT: FATAL - wget failed"
return 1
fi
log "NETBOOT: Download complete"
# Create mount points
mkdir -p "${SQUASHFS_MOUNT}" "${OVERLAY_TMPFS}"
# Mount squashfs
log "NETBOOT: Mounting squashfs..."
if ! mount -t squashfs /filesystem.squashfs "${SQUASHFS_MOUNT}" -o ro; then
log "NETBOOT: FATAL - squashfs mount failed"
return 1
fi
# Extract filename from URL
FILE_NAME=$(basename "${ROOT_URL}")
FILE_PATH="/${FILE_NAME}"
# Mount tmpfs for overlay
log "NETBOOT: Mounting tmpfs..."
if ! mount -t tmpfs -o size=2G tmpfs "${OVERLAY_TMPFS}"; then
log "NETBOOT: FATAL - tmpfs mount failed"
return 1
fi
mkdir -p "${OVERLAY_TMPFS}/upper" "${OVERLAY_TMPFS}/work"
# 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}
# Mount overlay
log "NETBOOT: Mounting overlay..."
if ! mount -t overlay -o "lowerdir=${SQUASHFS_MOUNT},upperdir=${OVERLAY_TMPFS}/upper,workdir=${OVERLAY_TMPFS}/work" overlay "${MOUNTPOINT}"; then
log "NETBOOT: FATAL - overlay mount failed"
return 1
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"
# Setup overlay if requested - need separate mount points
if [ -n "${OVERLAYROOT}" ]; then
# Create mount points
mkdir -p "${SQUASHFS_MOUNT}" "${OVERLAY_TMPFS}"
# Mount read-only SquashFS to separate location
if ! mount -t squashfs "${FILE_PATH}" "${SQUASHFS_MOUNT}" -o ro; then
log_failure_msg "Failed to mount SquashFS at ${SQUASHFS_MOUNT}"
rm -f "${FILE_PATH}"
return ${rc}
fi
log_begin_msg "SquashFS mounted at ${SQUASHFS_MOUNT}"
log_end_msg
log_begin_msg "Mounting tmpfs for overlay upper/work"
# Create tmpfs for upper and work directories
if ! mount -t tmpfs -o size=2G tmpfs_overlay "${OVERLAY_TMPFS}"; then
log_failure_msg "Failed to mount tmpfs for overlay"
umount "${SQUASHFS_MOUNT}"
rm -f "${FILE_PATH}"
return ${rc}
fi
# Create overlay structure
mkdir -p "${OVERLAY_TMPFS}/upper" "${OVERLAY_TMPFS}/work"
# Mount overlay combining read-only lower + writable upper onto /root
if ! mount -t overlay \
-o "lowerdir=${SQUASHFS_MOUNT},upperdir=${OVERLAY_TMPFS}/upper,workdir=${OVERLAY_TMPFS}/work" \
overlay_root "${MOUNTPOINT}"; then
log_failure_msg "Failed to mount overlay filesystem"
umount "${OVERLAY_TMPFS}"
umount "${SQUASHFS_MOUNT}"
rm -f "${FILE_PATH}"
return ${rc}
fi
log_end_msg
log_begin_msg "Overlay mounted at ${MOUNTPOINT} (lower=${SQUASHFS_MOUNT})"
log_end_msg
# Clean up downloaded image as it's now mounted
rm -f "${FILE_PATH}"
rc=0
else
# Direct SquashFS mount without overlay - mount directly to /root
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 "Mounted SquashFS without overlay at ${MOUNTPOINT}"
log_end_msg
rc=0
fi
else
log_failure_msg "Unknown filesystem type: ${FILE_NAME}"
rm -f "${FILE_PATH}"
fi
return ${rc}
}
# Standard mount hook wrappers expected by initramfs init
mount_top()
{
netboot_top
}
mount_premount()
{
netboot_premount
}
mount_bottom()
{
netboot_bottom
log "NETBOOT: SUCCESS - root mounted at ${MOUNTPOINT}"
return 0
}