Skip to content

feat(windows): add native Windows WHPX hypervisor support#476

Open
lilongen wants to merge 10 commits into
boxlite-ai:mainfrom
lilongen:feat/windows-whpx-support
Open

feat(windows): add native Windows WHPX hypervisor support#476
lilongen wants to merge 10 commits into
boxlite-ai:mainfrom
lilongen:feat/windows-whpx-support

Conversation

@lilongen
Copy link
Copy Markdown

@lilongen lilongen commented May 5, 2026

Summary

Adds native Windows support to BoxLite using the Windows Hypervisor Platform (WHPX) API. This enables BoxLite to run lightweight Linux VMs directly on Windows without WSL2, providing the same SDK interface across all three platforms (macOS, Linux, Windows).

What works:

  • Full VM lifecycle: create, start, exec, stop
  • OCI image pull and ext4 disk construction on Windows
  • Network connectivity (gvproxy + AF_UNIX vsock)
  • Multi-vCPU (up to 4 vCPUs)
  • Volume mounts (virtiofs via 9p)
  • Python SDK on Windows
  • Process isolation via Windows Job Objects

Depends on: boxlite-ai/libkrun#1

Architecture

┌──────────────────────────────────────────────────────────┐
│                    Python/Node SDK                        │
├──────────────────────────────────────────────────────────┤
│                  boxlite (Rust core)                      │
│  ┌────────────────┐  ┌──────────────┐  ┌─────────────┐  │
│  │   image_disk   │  │    krun/     │  │   jailer/   │  │
│  │  (ext4 build)  │  │  engine.rs   │  │ job_object  │  │
│  └────────────────┘  └──────────────┘  └─────────────┘  │
├──────────────────────────────────────────────────────────┤
│              boxlite-shim (subprocess)                    │
│  ┌────────────────┐  ┌──────────────┐  ┌─────────────┐  │
│  │   watchdog     │  │   libkrun    │  │  gvproxy    │  │
│  │  (Event-based) │  │  (WHPX VMM)  │  │  (DLL)      │  │
│  └────────────────┘  └──────────────┘  └─────────────┘  │
└──────────────────────────────────────────────────────────┘

Key Changes

VM Engine (src/boxlite/src/vmm/krun/)

  • engine.rs — Windows VM lifecycle: krun_start (non-blocking) + krun_wait (poll) + krun_stop (graceful). Linux/macOS use krun_start_enter (blocking process takeover).
  • context.rs — Merged imports for new libkrun APIs (krun_add_virtiofs3, krun_add_net_unixgram, krun_add_vsock, etc.)

Process Lifecycle (src/boxlite/src/vmm/controller/)

  • spawn.rsCREATE_SUSPENDED + Job Object + ResumeThread to eliminate TOCTOU. PID file written from parent.
  • watchdog.rs — Windows: named Events + parent handle monitoring (replaces Unix POLLHUP).
  • shim.rs — Graceful shutdown via krun_stop instead of Unix signals.

Sandbox (src/boxlite/src/jailer/)

  • job_object.rs — Windows Job Objects: process limits, memory limits, kill-on-close, network Silos.

Image & Disk (src/boxlite/src/images/)

  • image_disk.rs — Windows ext4 disk construction using bundled e2fsprogs + raw file I/O (no loop devices).

Networking

  • port.rs — TCP port availability checking for gvproxy.
  • socket_path.rs — Cross-platform Unix socket path handling.

Build System

  • build.rs (boxlite) — Windows dependency bundling (kernel, initrd, e2fsprogs, gvproxy DLL).
  • build.rs (libkrun-sys) — MSVC static library linking.
  • build.rs (libgvproxy-sys) — DLL import lib for Windows.

Guest Agent (src/guest/)

  • zygote.rs — Timeout-based container readiness (no pidfd on Windows).
  • mounts.rs — Conditional bind-mount logic.
  • virtiofs.rs — 9p mount fallback for Windows host.

CI & Scripts

  • .github/workflows/test-windows.yml — Windows build + unit test CI
  • .github/workflows/test-windows-e2e.yml — Windows E2E test workflow
  • scripts/build/build-windows-runtime.sh — Cross-compile Windows runtime deps
  • scripts/build/cross-compile-{kernel,e2fsprogs,gvproxy}-windows.sh

Platform Behavior Differences

Aspect macOS/Linux Windows
Hypervisor HVF / KVM WHPX
VM lifecycle krun_start_enter (blocking) krun_start + krun_wait (async)
Shutdown SIGTERM krun_stop API
Watchdog Pipe POLLHUP Named Event + parent handle
Sandbox sandbox-exec / seccomp Job Objects
Disk build losetup + mkfs.ext4 Bundled e2fsprogs (raw file)
Networking gvproxy (static lib) gvproxy (DLL)
Process spawn fork + pre_exec CREATE_SUSPENDED + Job Object

Testing

CI (post-rebase)

Check macOS ARM64 Linux (Lima)
cargo fmt PASS
cargo clippy PASS PASS
Unit tests 689/689 PASS 673 pass, 26 pre-existing fail (need /dev/kvm)

Manual E2E (Windows)

Test Suite macOS ARM64 Win11 (i5-1135G7) Win10 (i7-4770HQ)
vm-bench (8 tests) 8/8 PASS 8/8 PASS 8/8 PASS
net-test (8 tests) 8/8 PASS 8/8 PASS 8/8 PASS
BrowserBox (6 tests) 8/8 PASS 4/6 PASS* 6/6 PASS

*Win11 BrowserBox playwright_endpoint failure is an unrelated libcontainer issue (sends InitReady instead of IntermediateReady), not WHPX-related.

Test Plan

  • CI: macOS + Linux builds pass (zero regression)
  • CI: Windows build compiles
  • Manual: vm-bench on Windows (create/exec/stop)
  • Manual: net-test on Windows (networking, 4 vCPUs)
  • Review: Job Object sandbox security
  • Review: no secrets in committed files

Known Limitations

  1. vCPU cap: 4 — Sufficient for AI agent sandboxes. Can be raised later.
  2. No GPU passthrough — WHPX limitation. GPU workloads should use WSL2.
  3. First-boot image build slow — Large OCI images (>2GB) need several minutes for initial ext4 construction. Cached on subsequent boots.

Stats

84 files changed, +6,133 / -523 (1 squashed commit)

Copilot AI review requested due to automatic review settings May 5, 2026 09:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds native Windows support to BoxLite by integrating the Windows Hypervisor Platform (WHPX) backend and adapting core runtime, sandboxing, networking, and build/bundling paths to work cross-platform while keeping the same SDK surface.

Changes:

  • Introduces Windows-specific VM lifecycle + process control (async krun_start/wait, job objects, suspended spawn/resume, Windows watchdog/events, Ctrl+C handling).
  • Extends cross-platform runtime and guest behavior (AF_UNIX on Windows via uds_windows, virtiofs→9p fallback, ensuring virtual filesystems mounted in guest).
  • Updates build system/CI/scripts to bundle and validate Windows runtime deps (kernel/initrd/e2fsprogs/gvproxy DLL/import lib) and add Windows CI workflows.

Reviewed changes

Copilot reviewed 82 out of 84 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/test-utils/src/home.rs Use OS temp dir instead of hardcoding /tmp for tests.
src/test-utils/src/config_matrix.rs Gate a platform-specific test to macOS/Linux.
src/test-utils/src/cache.rs Cross-platform cache tempdir/symlink + Windows locking adjustments.
src/test-utils/Cargo.toml Make libc a Unix-only dependency.
src/guest/src/storage/volume.rs Make SHARED virtiofs mount optional with fallback directory creation.
src/guest/src/storage/virtiofs.rs Implement virtiofs-first with 9p fallback; improve logging/errors.
src/guest/src/service/server.rs Set TCP_NODELAY on accepted TCP connections to reduce latency.
src/guest/src/service/guest.rs Make guest network configuration failures non-fatal.
src/guest/src/mounts.rs Add virtual filesystem mounting + generalized mount-type detection helper.
src/guest/src/main.rs Ensure /proc,/sys,/dev mounted early in guest startup.
src/guest/src/container/zygote.rs Add init-container build IPC types + handlers and tests.
src/guest/src/container/start.rs Route init container creation through zygote (avoid musl clone3 deadlock).
src/deps/libkrun-sys/src/lib.rs Add new WHPX-related libkrun FFI functions; gate uid/gid setters to Unix.
src/deps/libkrun-sys/build.rs Add Windows staticlib build/link path (WHPX) + make install-name fixup no-op on Windows.
src/deps/libgvproxy-sys/gvproxy-bridge/main.go Add TCP listen mode (listen_addr) and adjust cleanup/accept logic for Windows.
src/deps/libgvproxy-sys/build.rs Support Windows DLL import-lib workflow via LIBGVPROXY_PREBUILT.
src/boxlite/src/vmm/krun/context.rs Add async start/wait/stop + console output reader and Windows net backend hook.
src/boxlite/src/vmm/controller/watchdog.rs Add Windows watchdog implementation (Event + parent process handle).
src/boxlite/src/vmm/controller/spawn.rs Windows: CREATE_SUSPENDED, Job Object assignment, resume threads, PID file write from parent.
src/boxlite/src/vmm/controller/shim.rs Windows-aware graceful stop (event-driven waiting / termination); keep Unix SIGTERM flow.
src/boxlite/src/util/process.rs Add Windows implementations for is_process_alive/kill_process and stubs for wait semantics.
src/boxlite/src/util/mod.rs Disable Windows library path detection (static link) and suppress unused vars on non-Unix.
src/boxlite/src/util/binary_finder.rs Support ;-separated runtime dirs and .exe lookup on Windows.
src/boxlite/src/system_check.rs Add WHPX availability probing via dynamic WinHvPlatform loading + tests.
src/boxlite/src/runtime/signal_handler.rs Implement Windows console control handler using SetConsoleCtrlHandler.
src/boxlite/src/runtime/rt_impl.rs Use in-memory lock manager on non-Unix; adapt shutdown/force-kill logic for Windows.
src/boxlite/src/runtime/lock.rs Implement Windows home-dir locking via LockFileEx.
src/boxlite/src/runtime/layout.rs Skip same-filesystem validation on non-Unix.
src/boxlite/src/runtime/embedded.rs Make embedded runtime path assertions separator-aware.
src/boxlite/src/rootfs/operations.rs Gate Unix-only rootfs permission fixups.
src/boxlite/src/rootfs/mod.rs Gate Unix-only rootfs builder/mount helpers.
src/boxlite/src/rootfs/guest.rs Gate guest rootfs builder methods for Unix/Windows + avoid unused fields.
src/boxlite/src/portal/connection.rs Use AF_UNIX on all platforms; add Windows AF_UNIX connector via uds_windows.
src/boxlite/src/net/socket_path.rs Make socket shortening Unix-only and no-op on Windows.
src/boxlite/src/net/port.rs Introduce a non-Unix TCP port allocator module (currently not wired into net).
src/boxlite/src/lock/mod.rs Make file-lock manager Unix-only; keep in-memory locks available everywhere.
src/boxlite/src/litebox/init/types.rs Add transport fields to init context; gate overlay/disk flags to Unix; Windows UID/GID defaults.
src/boxlite/src/litebox/init/tasks/vmm_spawn.rs Normalize transports to Unix sockets on all platforms; plumb ready transport back into init ctx.
src/boxlite/src/litebox/init/tasks/guest_rootfs.rs Gate guest rootfs preparation by platform; reduce unused imports.
src/boxlite/src/litebox/init/tasks/guest_init.rs Clarify/adjust network init comments and imports.
src/boxlite/src/litebox/init/tasks/guest_connect.rs Use transports from pipeline; add Windows AF_UNIX ready listener implementation.
src/boxlite/src/litebox/init/tasks/container_rootfs.rs Gate rootfs prep paths by platform; make Windows use disk-rootfs path.
src/boxlite/src/litebox/box_impl.rs Tune shutdown timing/logging for Windows WHPX and gate Unix signal usage.
src/boxlite/src/jailer/shim_copy.rs Skip copying libkrunfw on Windows.
src/boxlite/src/jailer/sandbox/mod.rs Add post_spawn hook; add Windows Job Object sandbox wiring.
src/boxlite/src/jailer/sandbox/composite.rs Propagate post_spawn to composed sandboxes.
src/boxlite/src/jailer/pre_exec.rs Mark pre-exec isolation hook Unix-only.
src/boxlite/src/jailer/mod.rs Gate preserved-fds and PID pre_exec wiring to Unix; add post-spawn delegation.
src/boxlite/src/jailer/common/rlimit.rs Gate rlimit utilities to Unix.
src/boxlite/src/jailer/common/pid.rs Gate PID-file writer to Unix.
src/boxlite/src/jailer/common/mod.rs Gate Unix-only common modules and errno helper; keep FS helpers cross-platform.
src/boxlite/src/jailer/common/fs.rs Gate inode-based test to Unix.
src/boxlite/src/jailer/builder.rs Gate preserved FD support to Unix.
src/boxlite/src/images/storage.rs Gate layer extraction helpers to Unix where applicable.
src/boxlite/src/images/object.rs Gate layer extraction path method to Unix; allow digest computation on Unix/Windows.
src/boxlite/src/images/mod.rs Gate LayerExtractor re-export to Unix.
src/boxlite/src/images/blob_source.rs Gate extraction logic to Unix; keep test-only helpers available.
src/boxlite/src/images/archive/mod.rs Gate archive extraction submodules to Unix; keep verifier/time common.
src/boxlite/src/disk/mod.rs Gate ext4 module exports to Unix/Windows; tighten re-exports under cfg.
src/boxlite/src/disk/ext4.rs Improve error messages for missing e2fsprogs and normalize Windows path separators for debugfs.
src/boxlite/src/disk/constants.rs Gate ext4 constants to Unix/Windows.
src/boxlite/src/db/migration/v6_to_v7.rs Make path assertions separator-aware.
src/boxlite/src/db/boxes.rs Cache a per-process “boot id” on non-Linux/macOS to stabilize behavior.
src/boxlite/src/db/base_disk.rs Mark helper as potentially dead-code under cfg-gated callers.
src/boxlite/src/bin/shim/main.rs Add Windows shutdown handlers + watchdog; keep Unix signal/pipe watchdog for Unix.
src/boxlite/src/bin/shim/crash_capture.rs Add Windows unhandled exception filter capture; gate Unix signal handlers.
src/boxlite/Cargo.toml Move Unix-only deps under cfg(unix); add windows-sys and uds_windows for Windows.
src/boxlite/build.rs Embed kernel/initrd on Windows and add kernel/initrd discovery via BOXLITE_KERNEL_DIR.
sdks/python/src/lib.rs Initialize tracing subscriber on Python module import (best-effort).
sdks/python/Cargo.toml Add tracing-subscriber dependency for Python SDK.
scripts/build/cross-compile-kernel-windows.sh Add kernel cross-compile script for WHPX runtime.
scripts/build/cross-compile-gvproxy-windows.sh Add gvproxy DLL/import-lib cross-compile script.
scripts/build/cross-compile-e2fsprogs-windows.sh Add e2fsprogs cross-compile script for Windows (mke2fs/debugfs).
scripts/build/build-windows-runtime.sh Orchestrate building a full Windows runtime bundle.
scripts/build/build-initrd-windows.sh Build an initrd with required modules and busybox init for WHPX.
docs/cross-platform-test-report-20260503.md Add test report documenting cross-platform results and fixes.
Cargo.lock Add uds_windows + windows-sys dependencies to lockfile.
.github/workflows/test-windows.yml Add Windows CI compile/clippy/unit test workflow using BOXLITE_DEPS_STUB=1.
.github/workflows/test-windows-e2e.yml Add manual self-hosted WHPX E2E workflow.
.cargo/config.toml Add MSVC rustflag /FORCE:MULTIPLE for staticlib libkrun symbol collisions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +270 to +282
/// Create a symlink (Unix) or directory junction (Windows), ignoring `AlreadyExists`.
fn symlink_or_exists(target: &Path, link: &Path, label: &str) {
match std::os::unix::fs::symlink(target, link) {
let result = {
#[cfg(unix)]
{
std::os::unix::fs::symlink(target, link)
}
#[cfg(not(unix))]
{
// Windows: use junction (works without elevated privileges, unlike symlinks)
std::os::windows::fs::symlink_dir(target, link)
}
};
Comment on lines 290 to +314
@@ -286,16 +298,34 @@ fn flock_exclusive(path: &Path) -> std::fs::File {
file
}

/// Acquire an exclusive file lock via `LockFileEx`.
#[cfg(not(unix))]
fn flock_exclusive(path: &Path) -> std::fs::File {
// On Windows, opening with exclusive write access provides basic locking.
// For test cache warm-up serialization, this is sufficient since the file
// is held open for the duration of the warm-up.
use std::fs::OpenOptions;
OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(path)
.unwrap_or_else(|e| panic!("acquire lock on {}: {e}", path.display()))
}
Comment on lines 13 to 20
use libkrun_sys::{
krun_add_disk2, krun_add_net_unixgram, krun_add_net_unixstream, krun_add_virtiofs3,
krun_add_vsock, krun_add_vsock_port2, krun_create_ctx, krun_disable_implicit_vsock,
krun_free_ctx, krun_init_log, krun_set_console_output, krun_set_env, krun_set_exec,
krun_set_gpu_options, krun_set_kernel, krun_set_nested_virt, krun_set_port_map,
krun_free_ctx, krun_get_console_output, krun_init_log, krun_set_console_output, krun_set_env,
krun_set_exec, krun_set_gpu_options, krun_set_kernel, krun_set_nested_virt, krun_set_port_map,
krun_set_rlimits, krun_set_root, krun_set_root_disk_remount, krun_set_vm_config,
krun_set_workdir, krun_setgid, krun_setuid, krun_split_irqchip, krun_start_enter,
krun_set_workdir, krun_split_irqchip, krun_start, krun_start_enter, krun_stop, krun_wait,
};
Comment on lines +1 to +16
//! TCP port allocation for Windows transport.
//!
//! On Unix, each box gets deterministic socket paths (`box.sock`, `ready.sock`,
//! `net.sock`). On Windows, Unix sockets are unavailable — libkrun WHPX bridges
//! vsock to TCP. This module allocates ephemeral TCP ports for each box.
//!
//! # Approach
//!
//! Bind `TcpListener` to `127.0.0.1:0`, read the OS-assigned port, then drop
//! the listener. Stateless — no global registry needed. The small TOCTOU window
//! is acceptable because the ephemeral port pool is large (~16k ports).

#![cfg(not(unix))]

use boxlite_shared::errors::{BoxliteError, BoxliteResult};
use std::net::{Ipv4Addr, SocketAddrV4, TcpListener};
Comment on lines +74 to +81
tracing::warn!(
"SHARED filesystem mount failed ({}), using plain directory at {}",
e,
mount_point.display()
);
std::fs::create_dir_all(&mount_point).ok();
Ok(())
}
@lilongen lilongen force-pushed the feat/windows-whpx-support branch from dc2e291 to 4bd43df Compare May 5, 2026 11:14
Copilot AI review requested due to automatic review settings May 5, 2026 12:03
@lilongen lilongen force-pushed the feat/windows-whpx-support branch from 4bd43df to 6f6a65d Compare May 5, 2026 12:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 84 out of 86 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +301 to +314
/// Acquire an exclusive file lock via `LockFileEx`.
#[cfg(not(unix))]
fn flock_exclusive(path: &Path) -> std::fs::File {
// On Windows, opening with exclusive write access provides basic locking.
// For test cache warm-up serialization, this is sufficient since the file
// is held open for the duration of the warm-up.
use std::fs::OpenOptions;
OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(path)
.unwrap_or_else(|e| panic!("acquire lock on {}: {e}", path.display()))
}
Comment on lines +270 to +282
/// Create a symlink (Unix) or directory junction (Windows), ignoring `AlreadyExists`.
fn symlink_or_exists(target: &Path, link: &Path, label: &str) {
match std::os::unix::fs::symlink(target, link) {
let result = {
#[cfg(unix)]
{
std::os::unix::fs::symlink(target, link)
}
#[cfg(not(unix))]
{
// Windows: use junction (works without elevated privileges, unlike symlinks)
std::os::windows::fs::symlink_dir(target, link)
}
};
Comment on lines +70 to +81
Err(e) if virtiofs.tag == mount_tags::SHARED => {
// SHARED mount is optional — on hosts without virtiofs/9p support
// (e.g., WHPX without matching kernel modules), fall back to a
// plain directory. Block devices mount into subdirs and still work.
tracing::warn!(
"SHARED filesystem mount failed ({}), using plain directory at {}",
e,
mount_point.display()
);
std::fs::create_dir_all(&mount_point).ok();
Ok(())
}
Comment thread src/guest/src/mounts.rs
Comment on lines +49 to +58
// Skip if already mounted (check by trying to read a known entry)
let probe = match fstype {
"proc" => p.join("self").exists(),
"devtmpfs" => p.join("null").exists(),
_ => p.join(".").read_dir().is_ok_and(|mut d| d.next().is_some()),
};
if probe {
tracing::debug!("{} already mounted, skipping", path);
continue;
}
Comment on lines +204 to +214
// Use uds_windows in a blocking task for the accept
let accept_path = path.clone();
race_ready_signal(
async move {
tokio::task::spawn_blocking(move || {
let listener = uds_windows::UnixListener::bind(&accept_path)?;
listener.accept().map(|_| ())
})
.await
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
},
Comment on lines +1 to +11
//! TCP port allocation for Windows transport.
//!
//! On Unix, each box gets deterministic socket paths (`box.sock`, `ready.sock`,
//! `net.sock`). On Windows, Unix sockets are unavailable — libkrun WHPX bridges
//! vsock to TCP. This module allocates ephemeral TCP ports for each box.
//!
//! # Approach
//!
//! Bind `TcpListener` to `127.0.0.1:0`, read the OS-assigned port, then drop
//! the listener. Stateless — no global registry needed. The small TOCTOU window
//! is acceptable because the ephemeral port pool is large (~16k ports).
Complete Windows native VM support using WHPX (Windows Hypervisor Platform).
This enables BoxLite to run lightweight VMs on Windows without WSL2, using
the same hardware-level isolation as macOS (Hypervisor.framework) and Linux (KVM).

Key capabilities:
- WHPX hypervisor backend with full x86_64 guest support
- Multi-vCPU (up to 4) with INIT-SIPI-SIPI AP bootstrap
- Userspace IOAPIC + lock-free LAPIC with ICR broadcast IPI
- virtio-blk (async worker), virtio-net, virtio-vsock, virtio-rng, virtio-balloon
- virtio-9p host filesystem sharing
- AF_UNIX host-guest communication (replacing TCP)
- gvproxy networking for full guest internet access
- QCOW2 COW disk overlays
- JobObject process sandbox isolation
- HLT tiered sleep + LAPIC timer throttle for performance
- OCI image support with ext4 disk creation

Iterations completed:
- Iter 1: Async Disk I/O
- Iter 2: IOAPIC + LAPIC interrupt architecture
- Iter 3: Multi-vCPU (2 vCPUs)
- Iter 4: virtio-rng + virtio-balloon
- Iter 5: HLT tiered sleep + LAPIC timer throttle
- Iter 6: JobSandbox + process isolation
- Iter 7: Lock-free atomic LAPIC
- Iter 8: 4-vCPU fix (ICR broadcast shorthand)

E2E test results:
- Win11 (i5-1135G7): vm-bench 8/8, net-test 8/8 (4 vCPUs)
- Win10 (i7-4770HQ): vm-bench 8/8, net-test 8/8 (4 vCPUs)
- macOS/Linux: zero regression (639 unit tests pass)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lilongen lilongen force-pushed the feat/windows-whpx-support branch from 6f6a65d to 96692eb Compare May 5, 2026 13:12
- Add #[cfg(unix)] to verify_diff_ids() call and method definition in
  object.rs, since verify_tarball depends on TarballReader which is
  unix-only
- Add #[cfg(unix)] to three verifier tests that call verify_tarball
- Update libkrun submodule to include cargo fmt + DummyIrqChip fixes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 5, 2026 13:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 84 out of 86 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

src/deps/libgvproxy-sys/gvproxy-bridge/main.go:513

  • logrus.Info doesn’t interpret the trailing values as structured fields; it will just print them as extra arguments. If you want key/value logging consistent with the rest of this file, use logrus.WithFields(...).Info(...) (same applies to the "Destroyed gvproxy instance" log below).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +301 to +314
/// Acquire an exclusive file lock via `LockFileEx`.
#[cfg(not(unix))]
fn flock_exclusive(path: &Path) -> std::fs::File {
// On Windows, opening with exclusive write access provides basic locking.
// For test cache warm-up serialization, this is sufficient since the file
// is held open for the duration of the warm-up.
use std::fs::OpenOptions;
OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(path)
.unwrap_or_else(|e| panic!("acquire lock on {}: {e}", path.display()))
}
Comment on lines +270 to +282
/// Create a symlink (Unix) or directory junction (Windows), ignoring `AlreadyExists`.
fn symlink_or_exists(target: &Path, link: &Path, label: &str) {
match std::os::unix::fs::symlink(target, link) {
let result = {
#[cfg(unix)]
{
std::os::unix::fs::symlink(target, link)
}
#[cfg(not(unix))]
{
// Windows: use junction (works without elevated privileges, unlike symlinks)
std::os::windows::fs::symlink_dir(target, link)
}
};
Comment on lines +1 to +16
//! TCP port allocation for Windows transport.
//!
//! On Unix, each box gets deterministic socket paths (`box.sock`, `ready.sock`,
//! `net.sock`). On Windows, Unix sockets are unavailable — libkrun WHPX bridges
//! vsock to TCP. This module allocates ephemeral TCP ports for each box.
//!
//! # Approach
//!
//! Bind `TcpListener` to `127.0.0.1:0`, read the OS-assigned port, then drop
//! the listener. Stateless — no global registry needed. The small TOCTOU window
//! is acceptable because the ephemeral port pool is large (~16k ports).

#![cfg(not(unix))]

use boxlite_shared::errors::{BoxliteError, BoxliteResult};
use std::net::{Ipv4Addr, SocketAddrV4, TcpListener};
Comment on lines +74 to +81
tracing::warn!(
"SHARED filesystem mount failed ({}), using plain directory at {}",
e,
mount_point.display()
);
std::fs::create_dir_all(&mount_point).ok();
Ok(())
}
Comment on lines 138 to +178
@@ -127,9 +157,26 @@ impl<'a> ShimSpawner<'a> {
drop(stdin); // close write end — shim sees EOF
}

// 9. Close read end in parent (child inherited it via fork)
// 9. Close read end in parent (child inherited it via fork on Unix)
// On Windows, ChildSetup is just a handle value — no cleanup needed.
drop(child_setup);

// 10. Write PID file (Windows only).
// On Unix, the pre_exec hook writes the PID file after fork via
// async-signal-safe syscalls. On Windows, pre_exec is not available,
// so we write it from the parent after spawn succeeds.
#[cfg(windows)]
{
let pid_file = self.layout.pid_file_path();
std::fs::write(&pid_file, child.id().to_string()).map_err(|e| {
BoxliteError::Storage(format!(
"Failed to write PID file {}: {}",
pid_file.display(),
e
))
})?;
}
Comment thread sdks/python/src/lib.rs
Comment on lines 30 to +35
#[pymodule(name = "boxlite")]
fn boxlite_python(m: &Bound<'_, PyModule>) -> PyResult<()> {
// Initialize tracing from RUST_LOG env var (ignore if already initialized)
let _ = tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.try_init();
lile and others added 2 commits May 5, 2026 22:23
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The `time` and `verifier` modules are only used by unix-gated code
(LayerExtractor and verify_diff_ids). Without cfg gates, Windows CI
reports dead_code and unused_imports warnings (-D warnings → errors).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 5, 2026 14:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 84 out of 86 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +279 to +281
// Windows: use junction (works without elevated privileges, unlike symlinks)
std::os::windows::fs::symlink_dir(target, link)
}
Comment on lines +301 to +314
/// Acquire an exclusive file lock via `LockFileEx`.
#[cfg(not(unix))]
fn flock_exclusive(path: &Path) -> std::fs::File {
// On Windows, opening with exclusive write access provides basic locking.
// For test cache warm-up serialization, this is sufficient since the file
// is held open for the duration of the warm-up.
use std::fs::OpenOptions;
OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(path)
.unwrap_or_else(|e| panic!("acquire lock on {}: {e}", path.display()))
}
Comment on lines +204 to +214
// Use uds_windows in a blocking task for the accept
let accept_path = path.clone();
race_ready_signal(
async move {
tokio::task::spawn_blocking(move || {
let listener = uds_windows::UnixListener::bind(&accept_path)?;
listener.accept().map(|_| ())
})
.await
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
},
Comment on lines +74 to +81
tracing::warn!(
"SHARED filesystem mount failed ({}), using plain directory at {}",
e,
mount_point.display()
);
std::fs::create_dir_all(&mount_point).ok();
Ok(())
}
Comment thread src/guest/src/mounts.rs
Comment on lines +60 to +70
if let Err(e) = mount(
Some(fstype),
p,
Some(fstype),
MsFlags::empty(),
None::<&str>,
) {
tracing::warn!("Failed to mount {} on {}: {}", fstype, path, e);
} else {
tracing::info!("Mounted {} on {}", fstype, path);
}
Comment thread sdks/python/src/lib.rs
Comment on lines 30 to +35
#[pymodule(name = "boxlite")]
fn boxlite_python(m: &Bound<'_, PyModule>) -> PyResult<()> {
// Initialize tracing from RUST_LOG env var (ignore if already initialized)
let _ = tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.try_init();
lile and others added 2 commits May 5, 2026 23:09
GRACEFUL_SHUTDOWN_TIMEOUT_SECS (only used by start_parent_watchdog,
unix-only) and SIGNAL_EXIT_CODE_BASE (only used by crash_signal_handler,
unix-only) trigger dead_code errors on Windows with -D warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Split cli/terminal/mod.rs into unix.rs (existing code) + windows.rs
  (minimal StreamManager stub with Ctrl+C via tokio::signal::ctrl_c)
- Gate integration tests that use Unix-specific APIs with #![cfg(unix)]:
  recovery.rs (libc::kill), copy.rs (unix::fs::symlink),
  mount_security.rs (unix::fs::MetadataExt),
  sigstop_quiesce.rs (libc::kill/SIGSTOP)

The Windows CI workflow compiles all targets (--all-targets) even though
it only runs unit tests, so test code must also compile on Windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 6, 2026 00:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 91 out of 93 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +277 to +281
#[cfg(not(unix))]
{
// Windows: use junction (works without elevated privileges, unlike symlinks)
std::os::windows::fs::symlink_dir(target, link)
}
Comment on lines +304 to +312
// On Windows, opening with exclusive write access provides basic locking.
// For test cache warm-up serialization, this is sufficient since the file
// is held open for the duration of the warm-up.
use std::fs::OpenOptions;
OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(path)
Comment on lines +351 to +355
let guest_shutdown_timeout = if cfg!(windows) {
// Short timeout: if gRPC connection is already established, the
// shutdown RPC completes in <50ms. If not (networking disabled),
// we bail quickly — the shim watchdog will exit on keepalive signal.
Duration::from_millis(200)
Comment on lines +539 to +543
// On explicit stop, the parent (box_impl.rs) already tried Guest.Shutdown()
// RPC — skip the redundant attempt to avoid a 3s timeout when networking
// is unavailable. On parent death, we're the last chance to flush qcow2.
if !explicit_stop {
do_graceful_shutdown(transport);
Comment on lines +75 to +80
"SHARED filesystem mount failed ({}), using plain directory at {}",
e,
mount_point.display()
);
std::fs::create_dir_all(&mount_point).ok();
Ok(())
lile and others added 4 commits May 6, 2026 13:11
… import

- Gate test_extract_layer_preserves_whiteout_markers_for_cache with
  #[cfg(unix)] since extract_layer() is unix-only
- Add QueryInformationJobObject to windows_sys import in job_object.rs
  (used in test_job_object_has_die_on_exception_and_kill_on_close and
  test_job_object_has_ui_restrictions)
- Move #[cfg(any(linux, macos))] from assert to function level in
  standard_mode_enables_jailer test to avoid unused variable on Windows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move 55 documentation files + 1 compat-check script from the main
worktree into this WHPX-feature worktree where they belong. These
are byproducts of the Windows WHPX native support iteration work
(Iter 1–8) and were authored across the WHPX development sessions.

Categories:
- WHPX iteration plans, progress reports, review reports
- Architecture / E2E test reports for Win10 / Win11
- libwkrun research + design docs (Windows-native libkrun alternative)
- VM-internals deep-dive (in-depth-{01..08}, in-depth-cn-{01..08})
- VM creation / benchmarking comparison docs
- 9p kernel support investigation (Windows VirtIO-9P alternative)
- Cross-cutting research (microvm vs QEMU, virtio protocol, market scan)
- PR-summary artifacts from prior WHPX PR drafting

No source code change. Generated docs only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the WHPX-iteration slash commands from the main worktree:
- win10-{setup,sync,rebuild,test,e2e}.md
- win11-{setup,sync,rebuild,test,e2e}.md
- md-to-pdf.md (used to publish docs/*.pdf during WHPX work)

These automate the build/sync/test loop against the Win10 MBP and
Win11 T14 dev machines documented in CLAUDE.md, and the PDF export
used for review handoff.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- docs/boxlite-deps.md: dependency surface analysis written during
  WHPX porting work to understand which crates would need windows-msvc
  support.
- docs/{en.,}github-light.css: stylesheets used by the md-to-pdf
  slash command (committed in the previous commit) to render the
  WHPX docs/*.md → docs/*.pdf review artifacts in a github-light
  theme.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 26, 2026 09:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants