Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Prerelease] - Unreleased

## [v0.21.0]

### Added

- `AppSandbox::snapshot_with_scratch_mb` takes a snapshot with another scratch size, which the sandbox continues on and a restore of the snapshot gets: boot with what unpacking the rootfs needs, then run guest function calls with what they need, less or more. The snapshot records the size (`snapshot_scratch_mb`), as do later snapshots of the sandbox. A size too small for the kernel makes the sandbox's next entry, the restore, and a boot from the snapshot fail (restoring a snapshot that fits recovers the sandbox). A guest function call that runs out of scratch ends with its process killed (status 137 with a single-process driver, such as python's) or the guest aborted, depending on what runs out first. A restore recovers the sandbox.
Expand All @@ -12,10 +14,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

### Changed

- The host places the transport arena at a fixed address below the top of scratch, so a snapshot keeps it when restored with a different scratch size. Snapshots saved by an earlier release are refused: save them again. A native Unikraft kernel (`--kernel`, `SandboxBuilder::from_kernel`) built against an earlier `plat/hyperlight` can allocate over the arena: rebuild it against this kernel tree.
- Snapshots saved by v0.20.1 and earlier releases are refused (the kernel, the host's memory layout and the hyperlight-host dependency changed); save them again.
- The host places the transport arena at a fixed address below the top of scratch, so a snapshot keeps it when restored with a different scratch size.
- `hyperlight-host` and `hyperlight-common` move to 0.19. Hyperlight 0.19 gives the guest no heap region (hyperlight-dev/hyperlight#1968): the memory the guest allocates from is scratch. The kernel took its 1 MiB boot stack from that region, and now keeps it in its own image. The re-exported `hyperlight_host` is 0.19: its `SandboxConfiguration::set_heap_size`, `SandboxConfiguration::DEFAULT_HEAP_SIZE`, `SandboxBuilder::heap_size` and `SandboxBuilder::get_heap_size` (hyperlight's builder, not hluk's) are gone (size scratch instead), and `HostFunctions`, `Snapshot` (and what takes or returns one), `Error::Hyperlight`, and the interrupt handle `AppSandbox::interrupt_handle` returns and `SandboxBuilder::on_interrupt_handle` hands over are 0.19's types. For Hyperlight 0.19's other breaking changes (among them `PtRootFinder` gets a `SnapshotMemoryReader` and returns `Result<Vec<u64>>`, `Sandbox::snapshot` removes `map_region` and `map_file_cow` regions, snapshot ABI 9), see [its CHANGELOG](https://github.com/hyperlight-dev/hyperlight/blob/v0.19.0/CHANGELOG.md). A native Unikraft kernel (`--kernel`, `SandboxBuilder::from_kernel`) built against an earlier `plat/hyperlight` no longer boots: rebuild it against this kernel tree. `plat/hyperlight` now selects paging and refuses a build without a boot allocator, and the guest crashes if the canary word at the bottom of its 1 MiB boot stack (the init thread's, which also runs a native `main()` without `LIBUKBOOT_MAINTHREAD`) is found overwritten at the end of boot, at the start of an entry from the host, at the end of a call's entry, or at a shutdown.
- A `NetworkFilter`'s `allows` is asked at each send on a connected UDP socket rather than at its `connect()`, as it already was at an unconnected `sendto()`; a TCP connect is asked about as before. A `BlockList` looks its names up at those sends too, rather than at the UDP `connect()`.
- CI: on the Linux arm64 runner, a failure of the `http-express` demo or of the `smolagents` or `mcp` integration jobs no longer fails the run: under nested virtualization their guest's vCPU wedges (hyperlight-dev/hyperlight#2025), so the nightly is not red for that known cause. They still run and log; macOS, Windows and every other job stay strict.
- CI: a wedged HTTP demo fails once its five-minute wait for an answer runs out (60 tries, each a 3 s request and a 2 s pause), instead of holding its job until the timeout (the Linux arm64 nightly's demos job sat at its 90-minute ceiling): the demo harness captures the server's output to a file instead of a pipe it never drained, and stops the server with a bounded terminate, then kill.

### Fixed

- Under a restricted network policy (`AllowList`, `BlockList` or `Filter`), a name lookup with `AI_ADDRCONFIG`, as Node makes for a connection to a hostname, failed with `getaddrinfo EACCES` (#247): musl probes the address families it can use with a UDP `connect()`, to loopback among others, which the policy refused. A UDP `connect()` sends nothing, so it is no longer checked, and keeps the host's own errors; each send on a connected UDP socket is checked instead, against its peer, after a reconnect or an `AF_UNSPEC` disconnect too, as an unconnected `sendto()` already was. TCP is checked at its connect, as before.
- The kernel allocated scratch pages the host reserves at the top of scratch. It now stops below them.
- A guest that ran out of scratch during a copy-on-write fault crashed the VM (an unexpected exit) instead of aborting.
- On x86, a page fault the kernel could not handle early in boot or in its fault handler ended the guest as if it had finished: a guest function call that hit one looked complete. The guest aborts.
Expand Down
24 changes: 13 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 4 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hyperlight-unikraft"
version = "0.20.1"
version = "0.21.0"
edition = "2024"
description = "Run ordinary Linux programs inside Hyperlight micro-VMs using a Unikraft unikernel as the guest kernel — the hluk CLI and library."
license = "Apache-2.0"
Expand Down Expand Up @@ -38,7 +38,7 @@ mshv = ["hyperlight-host/mshv3"]
cpio = ["dep:tar"]

[dependencies]
hyperlight-common = "0.18"
hyperlight-common = "0.19"
serde_json = "1"
thiserror = "2"
tracing = "0.1"
Expand Down Expand Up @@ -85,12 +85,12 @@ sha2 = { version = "0.11", optional = true }
# Windows — WHP, compiled in unconditionally for the target (no feature).
# macOS — Hypervisor.framework via the default `hvf` feature.
[target.'cfg(target_os = "linux")'.dependencies]
hyperlight-host = { version = "0.18", default-features = false, features = ["kvm", "build-metadata"] }
hyperlight-host = { version = "0.19", default-features = false, features = ["kvm", "build-metadata"] }

# Non-Linux keeps hyperlight's defaults: HVF (macOS) is on, WHP (Windows) is
# unconditional, and the Linux-only kvm/mshv3 features are inert here.
[target.'cfg(not(target_os = "linux"))'.dependencies]
hyperlight-host = "0.18"
hyperlight-host = "0.19"

[target.'cfg(windows)'.dependencies]
# Private working set for the bench RSS line (already in the tree via clap).
Expand All @@ -103,10 +103,3 @@ tracing-subscriber = { version = "0.3", default-features = false, features = ["r
# The FlatBuffer decoder's external-value source, mirrored in the tests.
anyhow = "1"
bytes = "1"

# hyperlight main, for scratch resize (#1947) and scratch_allocated_bytes
# (#2019). crates.io takes no git dependency, so hyperlight-unikraft is not
# published until a hyperlight release replaces this.
[patch.crates-io]
hyperlight-host = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "6c17f7cd4e78b03d77fadf4cfe749d7ede96b7ab" }
hyperlight-common = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "6c17f7cd4e78b03d77fadf4cfe749d7ede96b7ab" }
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
use sha2::{Digest, Sha256};

/// The host side of the guest contract: the host functions and their
/// meaning, the virtqueue pool sizes, the heap, scratch and initrd layout,
/// meaning, the virtqueue pool sizes, the scratch and initrd layout,
/// the guest MSR list, and the hyperlight-host release that reads a
/// snapshot. Bump it when any of those changes in a way a snapshot would
/// notice; a kernel change rolls the key by itself.
Expand Down
5 changes: 2 additions & 3 deletions defconfig-elfloader
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
CONFIG_UK_NAME="elfloader"
CONFIG_PLAT_HYPERLIGHT=y
# Paging + vmem (must be explicit — elfloader's imply doesn't stick)
CONFIG_LIBUKPAGING=y
CONFIG_LIBUKFALLOC=y
# PLAT_HYPERLIGHT selects paging.
# vmem must be explicit (elfloader's imply doesn't stick).
CONFIG_LIBUKVMEM=y
CONFIG_LIBUKVMEM_DEFAULT_BASE=0x0000001000000000
CONFIG_LIBUKVMEM_DEMAND_PAGE_IN_SIZE=12
Expand Down
28 changes: 15 additions & 13 deletions demos/pptx-gen/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 0 additions & 7 deletions demos/pptx-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,3 @@ dotenvy = "0.15"
anyhow = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

# hyperlight main, for scratch resize (#1947) and scratch_allocated_bytes
# (#2019). crates.io takes no git dependency, so hyperlight-unikraft is not
# published until a hyperlight release replaces this.
[patch.crates-io]
hyperlight-host = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "6c17f7cd4e78b03d77fadf4cfe749d7ede96b7ab" }
hyperlight-common = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "6c17f7cd4e78b03d77fadf4cfe749d7ede96b7ab" }
Loading
Loading