mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #303] [MERGED] fix(overlaybd): dispatch remote image I/O onto a dedicated remote-io runtime #331
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#331
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/303
Author: @huajq
Created: 9/18/2026
Status: ✅ Merged
Merged: 9/21/2026
Merged by: @yingdi-shan
Base:
main← Head:fix/remote-io-runtime📝 Commits (1)
574ec18fix(overlaybd): dispatch remote image I/O onto a dedicated remote-io runtime📊 Changes
10 files changed (+550 additions, -100 deletions)
View changed files
📝
config/default.toml(+1 -0)📝
docs/src/internals/architecture.md(+1 -0)📝
src/cfg.rs(+8 -0)📝
src/setup/deps.rs(+3 -1)📝
storage/overlaybd/src/backend/cache/full_file_cache/cache_store.rs(+4 -2)📝
storage/overlaybd/src/backend/oss.rs(+0 -71)📝
storage/overlaybd/src/config.rs(+8 -0)📝
storage/overlaybd/src/image/image_service.rs(+216 -26)➕
storage/overlaybd/src/io/dispatch_file.rs(+308 -0)📝
storage/overlaybd/src/io/mod.rs(+1 -0)📄 Description
What
Fix a runtime-ownership bug in remote image I/O: each ublk device queue runs its own
current_threadtokio runtime that is dropped on device teardown, while opendal (GLOBAL_REQWEST_CLIENT) and the cached operators share one process-wide reqwest connection pool. hyper spawns per-connection driver tasks onto whatever runtime polls a request, so pooled connections ended up owned by a random device's runtime — reads from other devices were coupled to that device's scheduling, and device teardown killed connections other devices were actively using.The fix introduces
RuntimeDispatchFileand routes all remote network I/O through a fixed runtime owned byImageService:open_backend_source_with_sizeruns the whole open (including the eager size fetch inRegistryFsV2::open) on the pinned runtime and wraps the opened OSS/registryfs files, so no request or steady-state read is ever polled on a caller's runtime regardless of what the open path does;tokio::spawncalls (download scheduler, eviction/checkpoint workers) bind to it without the cache internals needing to know;ublk.overlaybd.remote_io_workers(default 4, validated > 0; emitted asremoteIoWorkersinto generated overlaybd global configs). With it unset/zero (e.g. unit tests), remote I/O runs on the runtime that constructed theImageService;read_at_intooverride onOssFileis dropped — theVirtualFiletrait default (read_at+ copy) now serves those callers.Why
Pooled HTTP connections were being destroyed by unrelated ublk device teardowns, and cross-device reads were scheduled onto the wrong queue runtime — a correctness/stability bug for concurrent devices with remote layers (OSS snapshots, registry images).
Related issue
N/A
Scope and non-goals
Included: runtime dispatch for remote I/O, the
remote_io_workersconfig, theread_at_intooverride removal, docs note indocs/src/internals/architecture.md. Excluded: any behavior change to cache layout, wire protocols, or image formats.Design and behavior changes
ImageServiceruntime; device queue runtimes only see completion of dispatched futures.read_at_intoremoval (whole-range buffer + one copy instead of streamed chunks).Compatibility and operations
ublk.overlaybd.remote_io_workers(default 4, must be > 0).Validation
make fmtmake clippymake test-unit(focused suites)make -C services test— N/A (services/untouched)Commands and results:
Skipped checks and reasons: integration tests (no KVM on the build host used); the fix is exercised by unit tests.
Risks and reviewer notes
remote_io_workersworker count is perImageServiceinstance (the daemon holds one shared instance).read_at_intoremoval trades a little peak memory for the simpler default path; the dispatch runtime makes request lifetimes uniform regardless.storage/overlaybd/src/io/dispatch_file.rs, thenimage_service.rs, thenbackend/oss.rs.Checklist
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.