diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 8ae2d22..482f648 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -287,9 +287,9 @@ jobs: - name: "Snapshot size" if: steps.kvm_check.outputs.available == 'true' run: | - snap=".pyhl/snapshot.hls" - apparent=$(($(stat -c '%s' "$snap") / 1024 / 1024)) - disk=$(($(stat -c '%b' "$snap") * 512 / 1024 / 1024)) + snap=".pyhl/snapshot" + apparent=$(($(find "$snap" -type f -exec stat -c '%s' {} + | paste -sd+ | bc) / 1024 / 1024)) + disk=$(($(find "$snap" -type f -exec stat -c '%b' {} + | paste -sd+ | bc) * 512 / 1024 / 1024)) echo "| Metric | Value |" echo "|--------|-------|" echo "| Apparent size | ${apparent} MiB |" @@ -483,27 +483,29 @@ jobs: - name: "Snapshot size" shell: pwsh run: | - $snap = ".pyhl\snapshot.hls" - $f = Get-Item $snap - $apparentMiB = [math]::Round($f.Length / 1MB) - # GetCompressedFileSize returns actual on-disk allocation for sparse files - $wide = $f.FullName Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; - public class SparseHelper { - [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)] - public static extern uint GetCompressedFileSizeW(string lpFileName, out uint lpFileSizeHigh); + public class SparseFileHelper { + [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)] + public static extern uint GetCompressedFileSizeW(string lpFileName, out uint lpFileSizeHigh); } - "@ -ErrorAction SilentlyContinue - $high = [uint32]0 - $low = [SparseHelper]::GetCompressedFileSizeW($wide, [ref]$high) - if ($low -ne [uint32]::MaxValue) { - $diskBytes = ([uint64]$high -shl 32) -bor [uint64]$low - $diskMiB = [math]::Round($diskBytes / 1MB) - } else { - $diskMiB = $apparentMiB + "@ + function Get-CompressedSize($path) { + $high = [uint32]0 + $low = [SparseFileHelper]::GetCompressedFileSizeW($path, [ref]$high) + if ($low -eq 0xFFFFFFFF) { + $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() + if ($err -ne 0) { return (Get-Item $path).Length } + } + return ([uint64]$high -shl 32) -bor [uint64]$low } + $snap = ".pyhl\snapshot" + $files = Get-ChildItem -Path $snap -Recurse -File + $apparentMiB = [math]::Round(($files | Measure-Object -Property Length -Sum).Sum / 1MB) + $diskBytes = [uint64]0 + foreach ($f in $files) { $diskBytes += Get-CompressedSize $f.FullName } + $diskMiB = [math]::Round($diskBytes / 1MB) Write-Host "| Metric | Value |" Write-Host "|--------|-------|" Write-Host "| Apparent size | ${apparentMiB} MiB |" diff --git a/host/Cargo.lock b/host/Cargo.lock index bf20426..747974c 100644 --- a/host/Cargo.lock +++ b/host/Cargo.lock @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arbitrary" @@ -179,6 +179,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bstr" version = "1.12.3" @@ -413,6 +422,33 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "constant_time_eq" version = "0.4.2" @@ -615,14 +651,100 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", ] [[package]] @@ -739,6 +861,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "flatbuffers" version = "25.12.19" @@ -759,6 +887,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foldhash" version = "0.1.5" @@ -891,6 +1025,17 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "getset" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cf442baaabe4213ce7d1239afc26c039180b6456da2cededa316ae2c8a77a77" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "gimli" version = "0.32.3" @@ -960,6 +1105,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "http" version = "1.4.2" @@ -976,14 +1127,29 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "typenum", +] + [[package]] name = "hyperlight-common" -version = "0.15.0" -source = "git+https://github.com/danbugs/hyperlight?rev=5cf37d92#5cf37d92262c918e7d633577a6cf946fb1f069bd" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436dac5cc08da3db27de38b174a9b22498ab6443aaffd83b97f66a5d2f1d74cc" dependencies = [ "anyhow", + "bitflags 2.13.0", + "bytemuck", + "bytes", + "fixedbitset", "flatbuffers", "log", + "smallvec", "spin", "thiserror 2.0.18", "tracing", @@ -992,8 +1158,9 @@ dependencies = [ [[package]] name = "hyperlight-host" -version = "0.15.0" -source = "git+https://github.com/danbugs/hyperlight?rev=5cf37d92#5cf37d92262c918e7d633577a6cf946fb1f069bd" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef3edc7875e70a3b5cc291a17f78cfc352e24c9a665a5a1bbdbc46ada3df43b5" dependencies = [ "anyhow", "bitflags 2.13.0", @@ -1005,6 +1172,7 @@ dependencies = [ "crossbeam-channel", "flatbuffers", "goblin", + "hex", "hyperlight-common", "kvm-bindings", "kvm-ioctls", @@ -1014,15 +1182,18 @@ dependencies = [ "metrics", "mshv-bindings", "mshv-ioctls", + "oci-spec", "page_size", "rand 0.10.1", "rust-embed", + "serde", "serde_json", + "sha2 0.11.0", + "tempfile", "termcolor", "thiserror 2.0.18", "tracing", "tracing-core", - "tracing-log", "uuid", "vmm-sys-util", "windows", @@ -1041,7 +1212,6 @@ dependencies = [ "flate2", "hyperlight-host", "libc", - "memmap2", "nix", "serde_json", "socket2 0.5.10", @@ -1165,6 +1335,12 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.1.0" @@ -1262,6 +1438,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "kvm-bindings" version = "0.14.1" @@ -1273,9 +1464,9 @@ dependencies = [ [[package]] name = "kvm-ioctls" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "333f77a20344a448f3f70664918135fddeb804e938f28a99d685bd92926e0b19" +checksum = "06ac372c120eb893b086d1a12027669cf2b478d1f71204021ffa7adf57948d63" dependencies = [ "bitflags 2.13.0", "kvm-bindings", @@ -1409,15 +1600,6 @@ dependencies = [ "rustix 1.1.4", ] -[[package]] -name = "memmap2" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" -dependencies = [ - "libc", -] - [[package]] name = "metrics" version = "0.24.6" @@ -1527,6 +1709,23 @@ dependencies = [ "memchr", ] +[[package]] +name = "oci-spec" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df6f876ad774d6a676f7e968f5c3edacc32f90e65fe680a8b686235396556fb" +dependencies = [ + "const_format", + "derive_builder", + "getset", + "regex", + "serde", + "serde_json", + "strum", + "strum_macros", + "thiserror 2.0.18", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -1749,6 +1948,18 @@ dependencies = [ "smallvec", ] +[[package]] +name = "regex" +version = "1.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + [[package]] name = "regex-automata" version = "0.4.14" @@ -1812,7 +2023,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" dependencies = [ "globset", - "sha2", + "sha2 0.10.9", "walkdir", ] @@ -2004,7 +2215,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -2065,9 +2287,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "bd5231412d905519dca6a5deb0327d407be68d6c941feec004533401d3a0a715" dependencies = [ "lock_api", ] @@ -2084,6 +2306,24 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "subtle" version = "2.6.1" @@ -2264,17 +2504,6 @@ dependencies = [ "valuable", ] -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - [[package]] name = "typenum" version = "1.20.1" diff --git a/host/Cargo.toml b/host/Cargo.toml index 2c75c30..a1e57ba 100644 --- a/host/Cargo.toml +++ b/host/Cargo.toml @@ -31,11 +31,9 @@ default = [] wasm-host-fns = ["dep:wasmtime", "dep:wasmtime-wasi"] [dependencies] -# danbugs/hyperlight perf/whp-warm-start — snapshot file support + WHP warm-start optimizations. -hyperlight-host = { git = "https://github.com/danbugs/hyperlight", rev = "5cf37d92", features = ["executable_heap", "hw-interrupts", "whp-no-surrogate"] } +hyperlight-host = { version = "0.16.0", features = ["executable_heap", "hw-interrupts"] } clap = { version = "4", features = ["derive", "env"] } anyhow = "1" -memmap2 = "0.9" serde_json = "1" base64 = "0.22" socket2 = { version = "0.5", features = ["all"] } @@ -50,7 +48,7 @@ nix = { version = "0.29", features = ["fs"] } libc = "0.2" [target.'cfg(windows)'.dependencies] -windows-sys = { version = "0.61", features = ["Win32_System_IO", "Win32_System_Ioctl", "Win32_Storage_FileSystem", "Win32_Networking_WinSock"] } +windows-sys = { version = "0.61", features = ["Win32_Networking_WinSock", "Win32_System_IO", "Win32_System_Ioctl"] } [dev-dependencies] tempfile = "3" diff --git a/host/examples/pyhl_as_library.rs b/host/examples/pyhl_as_library.rs index 4e4f59f..6dd3571 100644 --- a/host/examples/pyhl_as_library.rs +++ b/host/examples/pyhl_as_library.rs @@ -3,7 +3,7 @@ //! //! Usage: `cargo run --release --example pyhl_as_library -- ` //! -//! Assumes `pyhl setup` has already run and `.pyhl/snapshot.hls` exists +//! Assumes `pyhl setup` has already run and `.pyhl/snapshot/` exists //! in the current directory (or override with `PYHL_HOME`). use hyperlight_unikraft::{pyhl, Preopen}; @@ -22,7 +22,7 @@ fn main() -> anyhow::Result<()> { // expose host directories via the guest's hostfs. let mounts: &[Preopen] = &[]; - let mut rt = pyhl::Runtime::new(&home, mounts, None, None)?; + let mut rt = pyhl::Runtime::new(&home, mounts, None, None, None)?; eprintln!("-- first run (hermetic from loaded snapshot) --"); let t1 = rt.run_code(&code)?; diff --git a/host/examples/test_cpiovfs.rs b/host/examples/test_cpiovfs.rs index 3d93cdd..def763d 100644 --- a/host/examples/test_cpiovfs.rs +++ b/host/examples/test_cpiovfs.rs @@ -21,9 +21,12 @@ fn main() -> anyhow::Result<()> { sbox.snapshot_now()?; eprintln!(" snapshot OK"); - let snap_path = "/tmp/cpiovfs_snapshot.hls"; + let snap_path = "/tmp/cpiovfs_snapshot"; sbox.save_snapshot(snap_path)?; - let snap_size = std::fs::metadata(snap_path)?.len(); + let snap_size: u64 = std::fs::read_dir(snap_path)? + .filter_map(|e| e.ok()) + .filter_map(|e| e.metadata().ok().map(|m| m.len())) + .sum(); eprintln!( " snapshot size: {} MiB ({} bytes)", snap_size / 1024 / 1024, diff --git a/host/src/bin/pydriver_run.rs b/host/src/bin/pydriver_run.rs index 4956f50..448f83c 100644 --- a/host/src/bin/pydriver_run.rs +++ b/host/src/bin/pydriver_run.rs @@ -44,7 +44,7 @@ fn main() -> Result<()> { let t_evolve = Instant::now(); let mut sandbox = Sandbox::builder(&kernel) .initrd_file(&initrd) - .heap_size(5 * 512 * 1024 * 1024) + .heap_size(1280 * 1024 * 1024) .build()?; eprintln!( "[timing] evolve={:.1}ms", diff --git a/host/src/bin/pyhl.rs b/host/src/bin/pyhl.rs index da4f898..ac66a48 100644 --- a/host/src/bin/pyhl.rs +++ b/host/src/bin/pyhl.rs @@ -223,6 +223,11 @@ struct SetupArgs { /// Repeatable: `--port 8080 --port 3000`. #[arg(long, value_name = "PORT")] port: Vec, + + /// Maximum surrogate processes (Windows only). 0 disables surrogates + /// entirely, using VirtualAlloc + WHvMapGpaRange (single-VM-per-process). + #[arg(long, value_name = "N")] + max_surrogates: Option, } #[derive(Args)] @@ -295,6 +300,11 @@ struct RunArgs { /// you want bit-for-bit reproducibility across calls). #[arg(long = "deterministic")] deterministic: bool, + + /// Maximum surrogate processes (Windows only). 0 disables surrogates + /// entirely, using VirtualAlloc + WHvMapGpaRange (single-VM-per-process). + #[arg(long, value_name = "N")] + max_surrogates: Option, } // -- image-home resolution ---------------------------------------------------- @@ -302,7 +312,7 @@ struct RunArgs { const CWD_HOME: &str = ".pyhl"; const KERNEL_FILE: &str = "kernel"; const INITRD_FILE: &str = "initrd.cpio"; -const SNAPSHOT_FILE: &str = "snapshot.hls"; +const SNAPSHOT_DIR: &str = "snapshot"; const VERSION_FILE: &str = "VERSION"; /// Resolve the image home to use. Tries (in order): explicit, PYHL_HOME, @@ -364,14 +374,16 @@ fn image_installed(home: &Path) -> bool { // -- `setup` ------------------------------------------------------------------ fn cmd_setup(args: SetupArgs) -> Result<()> { + hyperlight_unikraft::pyhl::configure_surrogates(args.max_surrogates); + let home = resolve_home(args.dest.as_deref(), ResolveMode::ForSetup)?; let dst_kernel = home.join(KERNEL_FILE); let dst_initrd = home.join(INITRD_FILE); - let dst_snapshot = home.join(SNAPSHOT_FILE); + let dst_snapshot = home.join(SNAPSHOT_DIR); let dst_version = home.join(VERSION_FILE); - if image_installed(&home) && dst_snapshot.is_file() && !args.force { + if image_installed(&home) && dst_snapshot.is_dir() && !args.force { eprintln!( "pyhl: image already installed at {} (use --force to overwrite)", home.display() @@ -451,7 +463,7 @@ fn cmd_setup(args: SetupArgs) -> Result<()> { { let mut builder = Sandbox::builder(&dst_kernel) .initrd_file(&dst_initrd) - .heap_size(5 * 512 * 1024 * 1024); + .heap_size(1280 * 1024 * 1024); for p in &setup_preopens { builder = builder.preopen(p.clone()); } @@ -494,12 +506,7 @@ fn cmd_setup(args: SetupArgs) -> Result<()> { dst_initrd.display(), mib(&dst_initrd) ); - eprintln!( - " snapshot: {} ({} MiB on disk, {} MiB apparent)", - dst_snapshot.display(), - disk_mib(&dst_snapshot), - mib(&dst_snapshot) - ); + eprintln!(" snapshot: {}", dst_snapshot.display()); Ok(()) } @@ -507,38 +514,6 @@ fn mib(p: &Path) -> u64 { fs::metadata(p).map(|m| m.len() / 1024 / 1024).unwrap_or(0) } -#[cfg(unix)] -fn disk_mib(p: &Path) -> u64 { - use std::os::unix::fs::MetadataExt; - fs::metadata(p) - .map(|m| m.blocks() * 512 / 1024 / 1024) - .unwrap_or_else(|_| mib(p)) -} - -#[cfg(windows)] -fn disk_mib(p: &Path) -> u64 { - use std::os::windows::ffi::OsStrExt; - let wide: Vec = p - .as_os_str() - .encode_wide() - .chain(std::iter::once(0)) - .collect(); - let mut high: u32 = 0; - let low = unsafe { - windows_sys::Win32::Storage::FileSystem::GetCompressedFileSizeW(wide.as_ptr(), &mut high) - }; - if low == u32::MAX { - return mib(p); - } - let bytes = ((high as u64) << 32) | (low as u64); - bytes / 1024 / 1024 -} - -#[cfg(not(any(unix, windows)))] -fn disk_mib(p: &Path) -> u64 { - mib(p) -} - /// Lightweight timestamp (seconds since epoch in ISO-8601-ish) so we don't /// need to pull chrono just for the VERSION stamp. fn now_iso8601() -> String { @@ -553,6 +528,8 @@ fn now_iso8601() -> String { // -- `run` -------------------------------------------------------------------- fn cmd_run(args: RunArgs) -> Result<()> { + hyperlight_unikraft::pyhl::configure_surrogates(args.max_surrogates); + let code = match (args.script.as_deref(), args.code.as_deref()) { (Some(_), Some(_)) => bail!("pass either