#!/bin/sh
#
# init — Linux guest init script for UTSM dual-kernel Linux compat layer.
#
# Boot sequence (phase 2 — Arch rootfs via virtio-blk /dev/vdb):
#   1. Mount essential filesystems (proc/sys/dev)
#   2. Wait for /dev/vdb (Arch rootfs virtio-blk device) to appear
#   3. Mount /dev/vdb as ext4 at /mnt/root
#   4. Copy /dev nodes + daemon (already baked into rootfs) into /mnt/root
#   5. switch_root /mnt/root /sbin/init
#   6. Arch /sbin/init starts utsm_exec_daemon → EXEC_READY → HLT (park)
#      → linux_launch() returns to UTSM
#
# Fallback (phase 1 — no rootfs, daemon in initramfs):
#   - If /dev/vdb never appears, start daemon directly from initramfs.
#   - If no daemon either, drop to interactive debug shell on ttyS0.
#
# The daemon runs forever, parking between requests. After switch_root,
# Arch /sbin/init owns PID 1 and must not exit.

PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

# Mount essential filesystems
mount -t proc none /proc 2>/dev/null
mount -t sysfs none /sys 2>/dev/null
mount -t devtmpfs none /dev 2>/dev/null

echo "[utsm-linux] init started"
echo "[utsm-linux] kernel: $(uname -r)"

# Verify /dev/utsm exists (driver is built-in, should be auto-created)
if [ ! -e /dev/utsm ]; then
    echo "[utsm-linux] WARNING: /dev/utsm not found — UTSM driver not loaded"
fi

# ===== Phase 2: switch_root to Arch rootfs on /dev/vdb =====
# The rootfs is exposed as a memory-backed virtio-blk device (GPA 0xF4002000,
# IRQ7). Wait up to ~5s for the kernel to discover it via devtmpfs.
echo "[utsm-linux] waiting for /dev/vdb (Arch rootfs)..."
VDB_OK=0
i=0
while [ $i -lt 50 ]; do
    if [ -b /dev/vdb ]; then
        VDB_OK=1
        break
    fi
    # 100ms sleep (busybox sleep supports fractional seconds)
    sleep 0.1
    i=$((i + 1))
done

if [ $VDB_OK -eq 1 ]; then
    echo "[utsm-linux] /dev/vdb found, attempting ext4 mount..."
    mkdir -p /mnt/root
    # Try ext4 (preferred); fall back to ext2 if ext4 module absent.
    if mount -t ext4 -o ro /dev/vdb /mnt/root 2>/dev/null || \
       mount -t ext2 -o ro /dev/vdb /mnt/root 2>/dev/null; then
        echo "[utsm-linux] rootfs mounted, verifying /sbin/init..."
        if [ -x /mnt/root/sbin/init ]; then
            echo "[utsm-linux] switch_root → Arch /sbin/init"
            # Move dev/proc/sys into new root so the Arch init can re-mount them.
            mount --move /dev  /mnt/root/dev  2>/dev/null
            mount --move /proc /mnt/root/proc 2>/dev/null
            mount --move /sys  /mnt/root/sys  2>/dev/null

            # ===== VSCode Phase 4: overlay 持久化（/dev/vdc extra-rootfs 可写卷）=====
            # rootfs 以 ro 挂载；/opt（VSCode 安装位置）、/home、/root 通过
            # overlayfs 获得可写层，upperdir/workdir 落在 /dev/vdc（virtio-blk
            # slot6 可写后端，内容跨启动持久）。vdc 缺失时保持 ro，安全降级。
            if [ -b /dev/vdc ]; then
                echo "[utsm-linux] /dev/vdc found, setting up overlay persistence..."
                modprobe overlay 2>/dev/null
                mkdir -p /mnt/persist
                if mount -t ext4 -o rw /dev/vdc /mnt/persist 2>/dev/null; then
                    for d in opt home root; do
                        mkdir -p /mnt/persist/overlay/$d/upper \
                                 /mnt/persist/overlay/$d/work \
                                 /mnt/root/$d
                        if mount -t overlay overlay \
                            -o lowerdir=/mnt/root/$d,upperdir=/mnt/persist/overlay/$d/upper,workdir=/mnt/persist/overlay/$d/work \
                            /mnt/root/$d 2>/dev/null; then
                            echo "[utsm-linux] overlay: /$d rw (persist)"
                        else
                            echo "[utsm-linux] WARNING: overlay /$d failed (stays ro)"
                        fi
                    done
                    # persist 卷搬进新 root，switch_root 后可在 /mnt/persist 访问
                    mkdir -p /mnt/root/mnt/persist
                    mount --move /mnt/persist /mnt/root/mnt/persist 2>/dev/null
                else
                    echo "[utsm-linux] WARNING: /dev/vdc mount failed (no persistence)"
                fi
            fi

            exec switch_root /mnt/root /sbin/init
            # switch_root does not return
        else
            echo "[utsm-linux] WARNING: /mnt/root/sbin/init missing, not switching"
            umount /mnt/root 2>/dev/null
        fi
    else
        echo "[utsm-linux] WARNING: ext4/ext2 mount of /dev/vdb failed"
        echo "[utsm-linux] available block devices:"
        ls -l /dev/vd* /dev/sd* 2>/dev/null
    fi
else
    echo "[utsm-linux] /dev/vdb not found after 5s — phase-1 fallback"
fi

# ===== Fallback: daemon directly from initramfs (phase 1) =====
if [ -x /bin/utsm_exec_daemon ]; then
    echo "[utsm-linux] starting utsm_exec_daemon from initramfs..."
    /bin/utsm_exec_daemon &
    DAEMON_PID=$!
    echo "[utsm-linux] daemon PID=$DAEMON_PID"
    # init must not exit — sleep forever to keep the kernel happy.
    echo "[utsm-linux] init: daemon running, entering idle hold"
    while true; do
        sleep 3600
    done
fi

# ===== Last resort: interactive debug shell on ttyS0 =====
# No daemon and no rootfs — bring-up smoke test only.
echo "[utsm-linux] WARNING: no daemon, no rootfs — starting interactive debug shell on ttyS0"
exec /bin/setsid /bin/cttyhack /bin/sh
