#!/bin/sh # 20-persistent-mount.sh — Mount persistent data partition and bind-mount writable paths if [ "$KUBESOLO_NOPERSIST" = "1" ]; then log "Running in RAM-only mode — no persistent storage" # Create tmpfs-backed directories so KubeSolo has somewhere to write mkdir -p /var/lib/kubesolo /var/lib/containerd /etc/kubesolo /var/log /usr/local return 0 fi # Load block device drivers before waiting (modules loaded later in stage 30, # but we need virtio_blk available NOW for /dev/vda detection) modprobe virtio_blk 2>/dev/null || true modprobe mmc_block 2>/dev/null || true # Trigger mdev to create device nodes after loading driver mdev -s 2>/dev/null || true # Resolve LABEL= syntax to actual block device path # The RPi cmdline uses kubesolo.data=LABEL=KSOLODATA which needs resolution WAIT_SECS=30 log "Waiting for data device: $KUBESOLO_DATA_DEV" case "$KUBESOLO_DATA_DEV" in LABEL=*) # Extract label name and resolve via blkid/findfs DATA_LABEL="${KUBESOLO_DATA_DEV#LABEL=}" RESOLVED="" for i in $(seq 1 "$WAIT_SECS"); do mdev -s 2>/dev/null || true RESOLVED=$(blkid -L "$DATA_LABEL" 2>/dev/null) || true if [ -z "$RESOLVED" ]; then RESOLVED=$(findfs "LABEL=$DATA_LABEL" 2>/dev/null) || true fi if [ -n "$RESOLVED" ] && [ -b "$RESOLVED" ]; then log "Resolved LABEL=$DATA_LABEL -> $RESOLVED" KUBESOLO_DATA_DEV="$RESOLVED" break fi sleep 1 done ;; *) # Direct block device path — wait for it to appear # Fallback: create device node from sysfs if devtmpfs/mdev didn't DEV_NAME="${KUBESOLO_DATA_DEV##*/}" if [ ! -b "$KUBESOLO_DATA_DEV" ] && [ -f "/sys/class/block/$DEV_NAME/dev" ]; then MAJMIN=$(cat "/sys/class/block/$DEV_NAME/dev") mknod "$KUBESOLO_DATA_DEV" b "${MAJMIN%%:*}" "${MAJMIN##*:}" 2>/dev/null || true log "Created $KUBESOLO_DATA_DEV via mknod ($MAJMIN)" fi for i in $(seq 1 "$WAIT_SECS"); do [ -b "$KUBESOLO_DATA_DEV" ] && break mdev -s 2>/dev/null || true sleep 1 done ;; esac if [ ! -b "$KUBESOLO_DATA_DEV" ]; then log_err "Data device $KUBESOLO_DATA_DEV not found after ${WAIT_SECS}s" # Comprehensive diagnostics for block device failure log_err "=== Block device diagnostics ===" log_err "--- /dev block devices ---" ls -la /dev/mmc* /dev/sd* /dev/vd* /dev/nvme* 2>/dev/null | while read -r line; do log_err " $line" done log_err "--- /sys/class/block (kernel registered) ---" ls /sys/class/block/ 2>/dev/null | while read -r line; do log_err " $line" done log_err "--- dmesg: MMC/SDHCI/emmc ---" dmesg 2>/dev/null | grep -i -e mmc -e sdhci -e emmc | while read -r line; do log_err " $line" done log_err "--- dmesg: regulator ---" dmesg 2>/dev/null | grep -i regulator | while read -r line; do log_err " $line" done log_err "--- dmesg: firmware/mailbox ---" dmesg 2>/dev/null | grep -i -e 'raspberrypi' -e 'mailbox' -e 'firmware' | while read -r line; do log_err " $line" done log_err "--- dmesg: errors ---" dmesg 2>/dev/null | grep -i -e 'error' -e 'fail' -e 'unable' | while read -r line; do log_err " $line" done log_err "--- Full dmesg (last 60 lines) ---" dmesg 2>/dev/null | tail -60 | while read -r line; do log_err " $line" done log_err "=== End diagnostics ===" log_err "" log_err "Dropping to debug shell in 10 seconds..." log_err "Run 'dmesg' to see full kernel log." log_err "Run 'ls /sys/class/block/' to check block devices." log_err "" sleep 10 # Drop to interactive shell instead of returning failure # (returning 1 with set -e causes kernel panic before emergency_shell) exec /bin/sh /dev/console 2>&1 fi # Mount data partition (format on first boot if unformatted) mkdir -p "$DATA_MOUNT" if ! mount -t ext4 -o noatime,nosuid,nodev "$KUBESOLO_DATA_DEV" "$DATA_MOUNT" 2>/dev/null; then log "Formatting $KUBESOLO_DATA_DEV as ext4 (first boot)" mkfs.ext4 -q -L KSOLODATA "$KUBESOLO_DATA_DEV" || { log_err "Failed to format $KUBESOLO_DATA_DEV" return 1 } mount -t ext4 -o noatime,nosuid,nodev "$KUBESOLO_DATA_DEV" "$DATA_MOUNT" || { log_err "Failed to mount $KUBESOLO_DATA_DEV after format" return 1 } fi log_ok "Mounted $KUBESOLO_DATA_DEV at $DATA_MOUNT" # Create persistent directory structure (first boot) for dir in kubesolo containerd etc-kubesolo log usr-local network; do mkdir -p "$DATA_MOUNT/$dir" done # Ensure target mount points exist mkdir -p /var/lib/kubesolo /var/lib/containerd /etc/kubesolo /var/log /usr/local # Bind mount persistent paths mount --bind "$DATA_MOUNT/kubesolo" /var/lib/kubesolo mount --bind "$DATA_MOUNT/containerd" /var/lib/containerd mount --bind "$DATA_MOUNT/etc-kubesolo" /etc/kubesolo mount --bind "$DATA_MOUNT/log" /var/log mount --bind "$DATA_MOUNT/usr-local" /usr/local log_ok "Persistent bind mounts configured"