#!/bin/sh # ============================================================ # init -- PID 1 for the hiperiso hypervisor host initramfs # # Boots a selected ISO as a KVM guest with full bootlogging. # Kernel cmdline parameters (set by ventoy_grub.cfg): # hiperiso_iso="/ISOs/redbear.iso" (may be empty for diag) # hiperiso_diag=1 (diagnostics mode) # hiperiso_trace_level, hiperiso_ram, hiperiso_cpus, ... # # Architecture: p1 (data, HIPERISO/VENTOY), p2 (VTOYEFI, unused), # p3 (HISOBOOT — payload: runtime.squashfs, OVMF.fd, trace, redbear.json) # # D3: Early log on p3 from second zero — EVERY path leaves an artifact. # D4: Bounded retry for data-partition discovery. # D11: Un-silenced mounts, mkdir check, read timeout. # D18: Label-match OR removable acceptance for data partition. # ============================================================ PATH="/usr/bin:/bin:/usr/sbin:/sbin" export PATH mkdir -p /proc /sys /dev /tmp /run mount -t proc proc /proc 2>/dev/null mount -t sysfs sysfs /sys 2>/dev/null mount -t devtmpfs devtmpfs /dev 2>/dev/null || mount -t tmpfs tmpfs /dev 2>/dev/null mount -t tmpfs tmpfs /tmp 2>/dev/null mount -t tmpfs tmpfs /run 2>/dev/null . /hiperiso-lib.sh _INIT_UPTIME=$(cut -d' ' -f1 /proc/uptime 2>/dev/null) printf '\n' printf '======================================================\n' printf ' hiperiso hypervisor host -- KVM ISO boot logger \n' printf '======================================================\n' printf '\n' # D3: payload partition + early log from second zero hiperiso_setup_p3 . /hv_harvest.sh hiperiso_hv_harvest # Parse cmdline + redbear.json overrides hiperiso_parse_cmdline if [ -n "${P3_PART:-}" ]; then hiperiso_parse_redbear_json fi # Diagnostics mode: delegate to dedicated script if [ "${HIPERISO_DIAG:-0}" = "1" ]; then exec /diag_boot.sh fi # Validate ISO path if [ -z "$HIPERISO_ISO_PATH" ]; then hiperiso_log "FATAL: hiperiso_iso= not set on kernel command line" hiperiso_log " No ISO specified and diagnostics mode not requested." exec /bin/sh fi if ! hiperiso_validate_iso_path "$HIPERISO_ISO_PATH"; then hiperiso_log "FATAL: unsafe ISO path: $HIPERISO_ISO_PATH — dropping to shell" exec /bin/sh fi if [ -n "$HIPERISO_LOG_DIR" ] && ! hiperiso_validate_log_dir "$HIPERISO_LOG_DIR"; then hiperiso_log "FATAL: unsafe log dir: $HIPERISO_LOG_DIR — dropping to shell" exec /bin/sh fi case "${HIPERISO_GUEST_RAM:-2048}" in ''|*[!0-9]*) hiperiso_log "FATAL: hiperiso_ram must be a positive integer: ${HIPERISO_GUEST_RAM:-}" exec /bin/sh ;; esac case "${HIPERISO_GUEST_CPUS:-2}" in ''|*[!0-9]*) hiperiso_log "FATAL: hiperiso_cpus must be a positive integer: ${HIPERISO_GUEST_CPUS:-}" exec /bin/sh ;; esac hiperiso_log "ISO path: $HIPERISO_ISO_PATH" hiperiso_log "Log dir: $HIPERISO_LOG_DIR" hiperiso_log "Trace: ${HIPERISO_TRACE_LEVEL:-standard}" hiperiso_log "RAM: ${HIPERISO_GUEST_RAM:-2048} MB" hiperiso_log "CPUs: ${HIPERISO_GUEST_CPUS:-2}" hiperiso_log "Debugcon: ${HIPERISO_DEBUGCON:-0}" # D4/D18/D11: data partition with retry if ! hiperiso_mount_data_with_retry; then exec /bin/sh fi # Mount runtime squashfs from p3 RUNTIME_MOUNT="/mnt/runtime" mkdir -p "$RUNTIME_MOUNT" if [ -n "${P3_PART:-}" ]; then RUNTIME_SQUASHFS="${P3_MOUNT}${P3_RUNTIME_SQUASHFS}" if [ -f "$RUNTIME_SQUASHFS" ]; then [ -e /dev/loop-control ] || mknod /dev/loop-control c 10 237 2>/dev/null || true if mount -t squashfs -o loop,ro,nosuid,nodev "$RUNTIME_SQUASHFS" "$RUNTIME_MOUNT" 2>>"/tmp/mount-errors.log"; then hiperiso_log "Mounted runtime squashfs at $RUNTIME_MOUNT" export RUNTIME_MOUNT export LD_LIBRARY_PATH="${RUNTIME_MOUNT}/usr/lib:${RUNTIME_MOUNT}/usr/lib64:${RUNTIME_MOUNT}/lib:${RUNTIME_MOUNT}/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" else hiperiso_log "FATAL: Failed to mount runtime squashfs $RUNTIME_SQUASHFS" tail -n 5 /tmp/mount-errors.log 2>/dev/null exec /bin/sh fi else hiperiso_log "WARNING: runtime squashfs not found at $RUNTIME_SQUASHFS" fi else hiperiso_log "WARNING: p3 not available — runtime squashfs unavailable" hiperiso_log " Boot will likely fail at QEMU launch" fi # Derive and create session directory (D8/D11) HIPERISO_LOG_DIR=$(hiperiso_derive_session_dir "$HIPERISO_LOG_DIR" "$HIPERISO_ISO_PATH") export HIPERISO_LOG_DIR LOG_DIR="${DATA_MOUNT}${HIPERISO_LOG_DIR}" LOG_DIR="${LOG_DIR%/}" # normalize: no trailing slash (paths join as $LOG_DIR/file) ISO_PATH="${DATA_MOUNT}${HIPERISO_ISO_PATH}" hiperiso_create_session_dir export LOG_DIR ISO_PATH P3_MOUNT DATA_MOUNT # D3: migrate early log into session if [ -n "${P3_PART:-}" ]; then hiperiso_migrate_early_log "$LOG_DIR" fi printf 'kernel_start\t%s\t%s\n' "${_INIT_UPTIME:-0}" "$(hiperiso_utc_iso)" >> "${LOG_DIR}/timing.dat" hiperiso_timing_mark "session_created" hiperiso_log "Session dir: $HIPERISO_LOG_DIR" # Session metadata + env hiperiso_write_session_meta "started" hiperiso_write_status "running" "mounted" hiperiso_write_env hiperiso_timing_mark "env_written" # KVM detection KVM_RESULT=$(/kvm_check.sh) printf 'KVM_CHECK_RESULT=%s\n' "$KVM_RESULT" >> "${LOG_DIR}/env.txt" case "$KVM_RESULT" in KVM_OK) hiperiso_log "KVM available -- proceeding with hypervisor boot" export KVM_AVAILABLE=1 KVM_STATUS="available" hiperiso_write_status "running" "kvm_ok" ;; KVM_FAIL:*) hiperiso_log "KVM check failed: ${KVM_RESULT#KVM_FAIL:}" export KVM_AVAILABLE=0 KVM_STATUS="unavailable" if [ "$HIPERISO_FALLBACK" != "1" ]; then hiperiso_write_status "failed" "fallback_no_kvm" /fallback_boot.sh exec /bin/sh fi hiperiso_log "Fallback forced -- continuing with TCG emulation" hiperiso_write_status "running" "tcg_emulation" ;; esac hiperiso_timing_mark "kvm_checked" # Verify ISO if [ ! -f "$ISO_PATH" ]; then hiperiso_log "FATAL: ISO file not found: $ISO_PATH" ls -la "$DATA_MOUNT" 2>/dev/null >> "${LOG_DIR}/env.txt" hiperiso_write_status "failed" "iso_not_found" hiperiso_run_report hiperiso_finalize_session "failed" "" "iso_not_found" exec /bin/sh fi hiperiso_log "ISO found: $ISO_PATH" hiperiso_timing_mark "iso_verified" # conf_replace plugin _modified_iso=$(sh /conf_replace.sh 2>"${LOG_DIR}/conf_replace.log" || true) if [ -n "$_modified_iso" ] && [ -f "$_modified_iso" ]; then ISO_PATH="$_modified_iso" export ISO_PATH hiperiso_log "Using modified ISO: $ISO_PATH" fi # Log flush daemon rm -f /tmp/hiperiso_done /log_flush.sh "$LOG_DIR" & LOG_FLUSH_PID=$! hiperiso_log "Log flush daemon started (PID $LOG_FLUSH_PID)" hiperiso_write_status "running" "launching_qemu" hiperiso_timing_mark "qemu_launching" # Launch QEMU /qemu_launch.sh QEMU_EXIT_CODE=$? # Flush and finalize touch /tmp/hiperiso_done hiperiso_timing_mark "qemu_returned" _wait=0 while kill -0 "$LOG_FLUSH_PID" 2>/dev/null; do _wait=$((_wait + 1)) [ "$_wait" -gt 10 ] && kill "$LOG_FLUSH_PID" 2>/dev/null && break sleep 1 done sync printf 'QEMU_EXIT_CODE=%s\n' "$QEMU_EXIT_CODE" >> "${LOG_DIR}/env.txt" hiperiso_write_status "running" "qemu_exited" "$QEMU_EXIT_CODE" if [ "$QEMU_EXIT_CODE" -eq 0 ]; then _session_status="complete" _session_stage="session_complete" else _session_status="failed" _session_stage="qemu_error" fi hiperiso_run_report hiperiso_timing_mark "report_done" hiperiso_finalize_session "$_session_status" "$QEMU_EXIT_CODE" "$_session_stage" hiperiso_timing_mark "session_finalized" hiperiso_timing_write_json # Summary printf '\n' printf '======================================================\n' printf ' hiperiso boot session complete \n' printf '======================================================\n' printf ' ISO: %s\n' "$HIPERISO_ISO_PATH" printf ' Session: %s\n' "$(hiperiso_session_id)" printf ' QEMU exit: %s\n' "$QEMU_EXIT_CODE" printf ' Logs: %s\n' "$LOG_DIR" printf '======================================================\n' printf '\n' ls -la "$LOG_DIR" 2>/dev/null printf '\n' # L-5: read with timeout printf 'Press ENTER to reboot, or type "shell" for recovery (auto-reboot in 60s): ' read -t 60 -r _response _read_exit=$? case "${_response:-}" in shell|sh) printf '\nDropping to recovery shell...\n' exec /bin/sh ;; esac [ "$_read_exit" -ne 0 ] && printf '\nTimeout — rebooting...\n' printf '\nRebooting...\n' sync if command -v reboot >/dev/null 2>&1; then reboot -f else printf 'b' > /proc/sysrq-trigger 2>/dev/null fi exec /bin/sh