Skip to content

feat(storage)!: add live root-disk growth - #1533

Open
appcypher wants to merge 3 commits into
appcypher/checkpoint-restore-clonefrom
appcypher/live-root-disk-growth
Open

feat(storage)!: add live root-disk growth#1533
appcypher wants to merge 3 commits into
appcypher/checkpoint-restore-clonefrom
appcypher/live-root-disk-growth

Conversation

@appcypher

@appcypher appcypher commented Sep 6, 2026

Copy link
Copy Markdown
Member

TL;DR

Grow owned managed and flat ext4 root disks without restarting, including checkpoint-backed qcow2 roots. This is #7, stacked directly on #1503 with no newer main changes, and depends on libkrun #124.

Description

  • Reuse the existing modify API and preserve explicit restart and next-start policies; shrinking and cloud/user-owned disk restrictions are unchanged.
  • Briefly pause to extend the writable block head, then resume and expand the mounted filesystem through the guest agent.
  • Record pending growth for forward recovery and keep snapshotting and compaction blocked until it completes.
  • Support stopped growth using a private staging head without modifying sealed ancestors or adding chain depth; old private bindings currently remain on disk.
  • Preserve each layer's actual capacity so older snapshots restore at their captured size after later growth.
  • Add protocol generation 9 requests, user docs, a live matrix and measured phase results; pin libkrun commit ec9f119dcc144f1c011fe62ebd224d660c2191a3 for reproducible builds.
  • Remove redundant Rust modification setters without deprecation: use memory, max_memory and root_disk_size instead of the _mib setters or oci_upper_size* aliases. Bare MiB integers and typed sizes remain supported; other SDKs and serialized fields are unchanged. This is an intentional source-breaking API cleanup.
msb modify worker --root-disk 8G
msb modify worker --root-disk 16G --next-start
sb.modify().root_disk_size(8192).apply().await?;
await sb.modify(root_disk_size=8192)
await sandbox.modify({ rootDiskSize: 8192 });
_, err := sb.Modify(ctx, m.ModifyOptions{RootDiskSizeMiB: 8192})

Test Plan

  • cargo fmt --all -- --check and pinned offline CLI check pass.
  • cargo test --offline -p microsandbox --lib -- --test-threads=1: 667 passed, three ignored; cargo test --offline -p microsandbox-cli --lib commands::modify: ten passed. An unchanged stale-socket test failed in an earlier parallel suite and passed alone and serially.
  • Focused ext4, runtime disk and protocol schema tests pass, including four external e2fsck checks and 135 companion device tests.
  • Focused Clippy passes with only the pre-existing derivable_impls and too_many_arguments lint classes allowed.
  • macOS debug/release live matrices and 16 one-shot 512 MiB to 4 GiB/8320 MiB scenarios pass, including allocated data, full restore, cold boot, immutable ancestors and 16 independent filesystem checks. Live first-growth CLI calls took 74–86 ms; separate smaller-grow phase measurements had 3.8–8.1 ms VM pauses. These live runs preceded the setter-only cleanup. See scripts/smoke/reports/root-disk-growth-2026-09-06.md for coverage and limitations.
  • Linux/KVM and Windows/WHP live qualification, native language SDK runs and additional fault/load testing (source transfers await explicit destination approval).

Confidence Score: 5/5

The PR appears safe to merge based on the reviewed changes, with no concrete blocking or independently actionable non-blocking issue identified.

The growth path validates the guest filesystem before mutation, records forward-recovery state before changing capacity, preserves sealed layers during stopped growth, verifies the resulting guest capacities, and fences snapshots and compaction while completion is pending.

Reviews (1): Last reviewed commit: "refactor(sdk)!: remove redundant modific..." | Re-trigger Greptile

Extend the existing modify path to grow managed and flat ext4 roots,
including checkpoint-backed qcow2 heads, without changing sealed layers.
Persist pending growth for forward recovery and support staged stopped
growth over the same logical disk chain.

Add guest protocol generation 9 preflight and resize acknowledgments,
per-layer snapshot capacities, user documentation, and a macOS live
qualification harness and report. Pin the exact libkrun companion commit
until the capacity API is released.

Keep this change stacked directly on checkpoint-restore-clone (#6).
Linux and Windows qualification and source publication remain pending.
Exercise 512 MiB to 4 GiB and 8320 MiB across managed and flat roots,
raw and qcow2 heads, and live and stopped modification paths. Verify
allocated data, snapshot capacities, immutable ancestors and cold boots.

Add independent qemu-img and read-only e2fsck qualification on disposable
copies and record the macOS release timings and remaining coverage gaps.
No runtime behavior changes are included.
Use memory, max_memory and root_disk_size for both bare MiB integers
and typed sizes. Update CLI callers and documentation and verify both
input forms produce the same serialized patch values.

BREAKING CHANGE: remove memory_mib, max_memory_mib, root_disk_size_mib,
oci_upper_size and oci_upper_size_mib from SandboxModificationBuilder.
Use the unsuffixed setters; no deprecation aliases are retained.
Other SDK interfaces and wire fields are unchanged.
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.

1 participant