Implement prepared shared rootfs reuse as the primary deduped runtime path #48
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
geomind_code/my_hypervisor#48
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
This builds on the broader storage-deduplication work tracked in #35.
The current branch already caches pulled image contents, but it still materializes too much state per VM. The result is avoidable disk duplication and extra startup work when multiple VMs use the same image.
Current behavior
1. The cache stops at extracted rootfs
The image cache stores layers and can extract one shared rootfs per image digest, but there is no cached prepared runtime base for the shared-root path.
That means the cache helps with pulling and extracting, but not enough with the work required to actually run many VMs efficiently from the same image.
2. Backend selection is not capability-driven
Storage backend selection currently resolves directly to block storage unless
virtiofsis explicitly chosen.So even when the runtime environment could support a shared-root design, the normal path still pushes users toward a heavier per-VM block-image workflow.
3. Storage preparation consumes the runtime rootfs source directly
The storage preparation path uses the stored rootfs source directly instead of resolving a separate immutable prepared base for image-backed VMs.
That keeps the design centered around "prepare per VM" rather than "prepare once per image, then reuse many times".
4. Shared-root plus extra filesystem mounts needs valid hypervisor argument assembly
The hypervisor argument builder emits one
--fsentry for the root shared filesystem and then emits another--fsentry for each extra shared mount.That is fragile for hypervisor argument parsing. A VM with a shared-root base plus one or more additional shared mounts needs one valid combined filesystem-share argument structure, not repeated top-level flags assembled in a way that can break launch.
5. First-time prepared-base creation needs serialization
Once a prepared shared rootfs cache exists, cold starts from the same image/variant must not race each other. Without a per-image/per-variant lock, two concurrent first boots can both try to create the same prepared base.
Why this matters
Suggested implementation
Prepared image base
Backend policy
Per-VM state model
Hypervisor argument assembly
Concurrency
Acceptance criteria
Related work
Implementation Spec for Issue #48: Prepared Shared Rootfs Reuse
Objective
Eliminate per-VM rootfs duplication by introducing a prepared shared rootfs base cached per image digest and storage variant. Multiple VMs share one immutable prepared base, with only overlay/runtime data per-VM. Backend selection becomes capability-driven, and concurrent first-boot preparation is serialized with per-image locks.
Requirements
Files to Modify/Create
storage/prepared_base.rsstorage/mod.rspub mod prepared_basestorage/traits.rsprepared_base_pathandimage_digestto PrepareConfigstorage/virtiofs.rsstorage/block.rsstorage/volmgr_backend.rsstorage/image.rsinject_all_guest_binaries()vm/manager.rspaths.rsprepared_basespathconfig.rshypervisor/process.rsImplementation Plan
Step 1: Add prepared bases directory to Paths
Files:
paths.rs— Addprepared_basesfield, helper method, ensure_dirsStep 2: Consolidate binary injection helper
Files:
storage/image.rs— Createinject_all_guest_binaries()centralizing repeated injection codeStep 3: Create PreparedBaseManager module
Files:
storage/prepared_base.rs,storage/mod.rs— get_or_create with file locking, .ready markerStep 4: Update PrepareConfig
Files:
storage/traits.rs— Add prepared_base_path and image_digest fieldsStep 5: Refactor VirtioFsStorage
Files:
storage/virtiofs.rs— Use prepared base as lowerdir, skip injection when availableStep 6: Refactor BlockStorage
Files:
storage/block.rs— Use prepared base as source, skip injectionStep 7: Refactor VolmgrBackend
Files:
storage/volmgr_backend.rs— Snapshot from prepared base subvolumeStep 8: Integrate into VmManager
Files:
vm/manager.rs— Wire PreparedBaseManager into prepare_storage flowStep 9: Capability-driven backend auto-selection
Files:
vm/manager.rs,config.rs— "auto" default, capability probingStep 10: Concurrency and reuse tests
Files:
storage/prepared_base.rs— Thread-safety tests, reuse verificationStep 11: Verify multiple --fs flag assembly
Files:
hypervisor/process.rs— Test root + additional mounts produce valid argsAcceptance Criteria
Notes
Test Results
✅ All tests pass.
Implementation Summary
Files Created
crates/my_hypervisor-lib/src/storage/prepared_base.rs— PreparedBaseManager with file-locked get_or_create, .ready marker patternFiles Modified
crates/my_hypervisor-lib/src/paths.rs— Addedprepared_basespath + helper methodcrates/my_hypervisor-lib/src/storage/mod.rs— Registered prepared_base modulecrates/my_hypervisor-lib/src/storage/traits.rs— Addedprepared_base_pathandimage_digestto PrepareConfigcrates/my_hypervisor-lib/src/storage/image.rs— Consolidatedinject_all_guest_binaries()helpercrates/my_hypervisor-lib/src/storage/virtiofs.rs— Uses prepared base as overlay lowerdir, skips per-VM injectioncrates/my_hypervisor-lib/src/storage/block.rs— Uses prepared base as ext4 image sourcecrates/my_hypervisor-lib/src/storage/volmgr_backend.rs— Btrfs snapshot from prepared base with cp fallbackcrates/my_hypervisor-lib/src/vm/manager.rs— Integrated PreparedBaseManager, capability-driven auto backendcrates/my_hypervisor-lib/src/config.rs— Default backend changed to "auto"crates/my_hypervisor-lib/src/hypervisor/process.rs— Added multiple --fs flags testTest Results
300 tests, 300 passed, 0 failed
Notes