#!/bin/bash
#
# check-virtual-mounts.sh
#
# Read-only sanity check for LFS virtual filesystems.
# This script DOES NOT mount or unmount anything.
#
# Run from the HOST, not from inside the chroot.
#

: "${LFS:=/mnt/lfs}"

PASS=0
FAIL=0
WARN=0

pass() {
    printf '\033[1;32mPASS:\033[0m %s\n' "$*"
    PASS=$((PASS + 1))
}

fail() {
    printf '\033[1;31mFAIL:\033[0m %s\n' "$*"
    FAIL=$((FAIL + 1))
}

warn() {
    printf '\033[1;33mWARN:\033[0m %s\n' "$*"
    WARN=$((WARN + 1))
}

echo
echo "=============================================="
echo " LFS Virtual Filesystem Sanity Check"
echo "=============================================="
echo
echo "LFS=$LFS"
echo

# ------------------------------------------------------------
# Make sure LFS root exists
# ------------------------------------------------------------

if [ -d "$LFS" ]; then
    pass "LFS directory exists: $LFS"
else
    fail "LFS directory does not exist: $LFS"
    exit 1
fi


# ------------------------------------------------------------
# Function to verify one mount
# ------------------------------------------------------------

check_mount() {

    TARGET="$1"
    EXPECTED_TYPE="$2"

    if ! mountpoint -q "$TARGET"; then
        fail "$TARGET is NOT mounted"
        return
    fi

    TYPE=$(findmnt -n -o FSTYPE "$TARGET" | tail -1)

    if [ "$TYPE" = "$EXPECTED_TYPE" ]; then
        pass "$TARGET mounted as $TYPE"
    else
        fail "$TARGET mounted as '$TYPE' -- expected '$EXPECTED_TYPE'"
    fi
}


# ------------------------------------------------------------
# Check required mounts
# ------------------------------------------------------------

echo "Checking required virtual filesystems..."
echo

check_mount "$LFS/dev"     "devtmpfs"
check_mount "$LFS/dev/pts" "devpts"
check_mount "$LFS/proc"    "proc"
check_mount "$LFS/sys"     "sysfs"
check_mount "$LFS/run"     "tmpfs"


# ------------------------------------------------------------
# /dev/shm
# ------------------------------------------------------------

echo
echo "Checking shared memory..."

if [ -L "$LFS/dev/shm" ]; then

    pass "$LFS/dev/shm is a symbolic link"

    SHM_TARGET=$(readlink -f "$LFS/dev/shm")

    echo "      resolves to: $SHM_TARGET"

    if [ -d "$SHM_TARGET" ]; then
        pass "shared-memory target exists"
    else
        fail "shared-memory target does not exist"
    fi

elif mountpoint -q "$LFS/dev/shm"; then

    TYPE=$(findmnt -n -o FSTYPE "$LFS/dev/shm" | tail -1)

    if [ "$TYPE" = "tmpfs" ]; then
        pass "$LFS/dev/shm mounted as tmpfs"
    else
        fail "$LFS/dev/shm is mounted as $TYPE, expected tmpfs"
    fi

else

    warn "$LFS/dev/shm is neither a symlink nor a mountpoint"

fi


# ------------------------------------------------------------
# Detect duplicate/stacked mounts
# ------------------------------------------------------------

echo
echo "Checking for duplicate/stacked mounts..."
echo

for TARGET in \
    "$LFS/dev" \
    "$LFS/dev/pts" \
    "$LFS/proc" \
    "$LFS/sys" \
    "$LFS/run"
do

    COUNT=$(findmnt -rn -T "$TARGET" |
        awk -v target="$TARGET" '$1 == target {count++} END {print count+0}')

    if [ "$COUNT" -eq 1 ]; then
        pass "$TARGET has exactly one mount"
    elif [ "$COUNT" -eq 0 ]; then
        fail "$TARGET has no mount"
    else
        fail "$TARGET has $COUNT stacked mounts"
    fi

done


# ------------------------------------------------------------
# Specifically inspect host /dev/pts
# ------------------------------------------------------------

echo
echo "Checking host /dev/pts..."

HOST_PTS_COUNT=$(grep -c ' /dev/pts ' /proc/self/mountinfo)

if [ "$HOST_PTS_COUNT" -eq 1 ]; then
    pass "Host /dev/pts has exactly one devpts mount"
else
    fail "Host /dev/pts has $HOST_PTS_COUNT mounts"
    echo
    echo "      This may indicate mount propagation or"
    echo "      that the LFS mount commands were run repeatedly."
fi


# ------------------------------------------------------------
# Display actual mount layout
# ------------------------------------------------------------

echo
echo "=============================================="
echo " Current LFS Mount Layout"
echo "=============================================="
echo

findmnt "$LFS/dev" 2>/dev/null
findmnt "$LFS/dev/pts" 2>/dev/null
findmnt "$LFS/proc" 2>/dev/null
findmnt "$LFS/sys" 2>/dev/null
findmnt "$LFS/run" 2>/dev/null


# ------------------------------------------------------------
# Final result
# ------------------------------------------------------------

echo
echo "=============================================="
echo " RESULT"
echo "=============================================="
echo
echo "PASS: $PASS"
echo "WARN: $WARN"
echo "FAIL: $FAIL"
echo

if [ "$FAIL" -eq 0 ]; then

    echo "Virtual filesystem configuration looks good."
    echo "It should be safe to enter the LFS chroot."
    echo
    exit 0

else

    echo "Virtual filesystem configuration has problems."
    echo
    echo "DO NOT run the mount commands again blindly."
    echo "Investigate the FAIL entries first."
    echo
    exit 1

fi