mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #131] [MERGED] fix(overlaybd): isolate runtime and CLI cache directories #199
Labels
No labels
bug
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/AgentENV#199
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?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/AgentENV/pull/131
Author: @huajq
Created: 8/6/2026
Status: ✅ Merged
Merged: 8/7/2026
Merged by: @yingdi-shan
Base:
main← Head:fix/overlaybd-cache-isolation📝 Commits (1)
15f8dd9fix(overlaybd): isolate runtime and CLI cache directories📊 Changes
10 files changed (+449 additions, -50 deletions)
View changed files
📝
docs/src/internals/persistence-artifact-inventory.md(+3 -2)📝
src/cfg.rs(+97 -22)📝
src/image/resolver.rs(+3 -3)📝
src/sandbox/ublk/device.rs(+4 -0)📝
src/setup/deps.rs(+207 -12)📝
storage/ublk-daemon/src/client.rs(+4 -0)📝
storage/ublk-daemon/src/main.rs(+5 -0)📝
storage/ublk-daemon/src/runtime.rs(+74 -7)📝
storage/ublk-daemon/src/server.rs(+34 -2)📝
storage/ublk-daemon/tests/ublk_daemon_test.rs(+18 -2)📄 Description
What
Give every OverlayBD cache consumer its own
cacheDirinstead of sharing{image-cache}/remote-blocks:FileCacheBackend) →remote-blocks(unchanged)FileCacheBackend) →memory-blocksoverlaybd-apply(C++ file cache, OCI → overlaybd conversion) →convert-blocksoverlaybd-resize(C++ file cache) →resize-blocksoverlaybd-resizereceives its dedicated generated global config (resize-overlaybd-global.json) through a new daemon CLI argument, and daemon resize invocations are serialized under a daemon-wide permit. Config validation now also rejects user-configured rootfs/memory global config paths that collide with the derived convert/resize config paths.Why
All generated OverlayBD global configs pointed at the same
cacheDir(remote-blocks), with two distinct failure modes:overlaybd-apply,overlaybd-resize) initialize the C++ flat file cache on the shared directory. That cache recursively indexes every file it finds — including the Rust cache's<digest>/dataand<digest>/meta.bin— and its eviction doestruncate(0)+unlinkon them. With the Rust cache above ~90% ofcacheSizeGB, any tool invocation past the 10s eviction timer batch-empties Rust per-entry directories, andtruncate(0)on a live daemon mmap raises SIGBUS, killing the ublk daemon and all its devices.FileCacheBackendinstances (rootfs and memory) over the same directory. Each keeps its own bitmap/mmap/LRU and eviction worker, so one backend can hole-punch or delete entries the other still considers valid — the same class of corruption without any C++ process involved.overlaybd-applyhas no functional need for the cache at all (conversion only opens local layers).overlaybd-resizelegitimately reads remote lowers, so it keepscacheType=filewith on-demand reads in its own directory; background download is disabled for both tool configs.Related issue
N/A — no tracking issue.
Scope and non-goals
Included:
resize-overlaybd-global.jsonplumbed fromAppConfiginto the daemon (--resize-global-config) and used only for the resize child's--service_config_path; base-size resolution and post-resize verification keep using the runtime config.tokio::sync::Mutexpermit aroundoverlaybd-resize(the C++ cache has no cross-process coordination), released on success, non-zero exit, and timeout (kill + reap).known_source_virtual_size=None) shape.Non-goals (deliberately excluded):
CachePoolwith QoS for rootfs/memory (would avoid duplicated caching but is a larger cache-architecture change).image.cache.remote_blocks.max_size_gbindependently.Design and behavior changes
Generated config layout:
Resize config flow:
AppConfig::resolved_overlaybd_resize_global_config_path()→UblkDaemonConfig→UblkDaemonSpawnConfig→ daemon--resize-global-config→UblkDaemonServer→ per-connectionMaterializeOverlaybdRuntimeRequest→run_resize_tool. The resize permit is acquired immediately before spawning the child and dropped before Rust-side verification.Compatibility and operations
--resize-global-configCLI arg; server and daemon ship together, and the in-repo client is the only spawner.config.validate()now rejects rootfs/memory global config paths that alias the derived convert/resize config paths (previously silently overwritten at setup). No default behavior change.memory-blocksstarts cold once (existingremote-blockscontent is not migrated).Validation
make fmtmake clippymake test-unit(see note below)make -C services test(required whenservices/changes) — N/A, noservices/changesmaketarget — N/A, no generated code touchedCommands and results (Linux host with KVM/ublk):
End-to-end on the same host: created a sandbox with
diskSizeMBlarger than the base image (300 GiB on a 256 GiB image); observed the real invocationwith
resize-blocks/gaining the C++ cache entry andremote-blocks/containing only Rust per-entry directories afterwards; sandbox booted and the device showed the requested size.make test-unitnote: the single failure isprivileges::tests::scoped_spawn_clears_child_capabilities_without_mutating_caller(src/privileges.rs, untouched by this PR). It asserts a spawned child retains noCapPrm, which does not hold when tests run as root on this host; pre-existing and environment-dependent.Skipped checks and reasons: services tests, codegen, benchmarks — no related changes.
Risks and reviewer notes
image.cache.remote_blocks.max_size_gb, so worst-case aggregate cache usage grows;convert-blocksstays near-empty in practice (local-layer conversion only).overlaybd-applyprocesses shareconvert-blocks, but in the current pipeline conversion opens only local layers, so the C++ cache produces no remote entries there; revisit if conversion ever opens remote lowers.src/setup/deps.rs(four generated configs),src/cfg.rs(derived paths + collision validation),storage/ublk-daemon/src/runtime.rs(resize child config + permit).Checklist
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.