[3/N][Feat]Persist metadata on device and fix raw-device benchmark setup#2614
Conversation
…tests Replace file-manifest fallback with on-device metadata checkpoint handling and update rust raw block backend tests for the new recovery behavior and config surface. Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com>
Only create/truncate backing files for non-/dev paths so raw-device benchmark runs do not issue file truncate operations on block devices. Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com>
Summary of ChangesHello @DongDongJu, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly refactors the metadata persistence strategy for the Rust raw block storage backend. By moving from file-based manifests to on-device checkpointing, the system gains improved resilience and simplifies recovery processes. The changes also introduce configurable metadata formats and robust validation during loading, ensuring data integrity. Additionally, a critical fix was implemented for the storage backend microbenchmark to prevent unintended data truncation on actual raw devices, making the benchmarking process safer and more accurate. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request is a significant improvement, replacing the file-based manifest in RustRawBlockBackend with a more robust on-device metadata checkpointing system. The new implementation includes important reliability features like magic numbers, versioning, CRC checks for data integrity, and on-load validation of entries. The related unit tests have been updated and expanded to cover these new features, including scenarios with corrupted data, which is excellent. Overall, this is a high-quality change that enhances the backend's resilience. I have one suggestion to further improve the robustness of the state restoration logic.
- Validate next_slot/free_slots strictly when loading metadata - Deduplicate and range-check free slots - Avoid re-adding duplicate/invalid free slots in runtime paths - Ensure free list excludes slots already used by loaded index - Guard metadata region to require header + payload space Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request is a significant improvement, replacing the file-based manifest persistence in RustRawBlockBackend with a more robust on-device metadata checkpointing system. This change co-locates metadata with data, enhancing recovery semantics. The implementation is well-executed, featuring a new binary metadata format with versioning and CRC checks, a background thread for periodic checkpointing, and thorough validation of loaded metadata. The unit tests have been effectively updated to cover the new functionality, including scenarios for data offsets and corruption handling. Overall, this is a high-quality contribution that greatly improves the reliability of the raw block backend. I have one minor suggestion to enhance logging during metadata parsing to further improve debuggability.
…-metadata-journal # Conflicts: # benchmarks/storage_backend_io/storage_backend_io_benchmark.py # lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request significantly improves the RustRawBlockBackend by replacing the file-based manifest with a robust on-device metadata checkpointing system. This change is well-implemented, featuring versioning, integrity checks (magic numbers, CRCs), and thorough validation on load, which greatly enhances recovery and data safety. The shutdown process is also more robust, ensuring a final checkpoint is written. The unit tests have been updated accordingly, with new tests that validate the new on-device layout and recovery from corruption. Overall, this is an excellent enhancement. I've included a few minor suggestions to improve code clarity and exception handling.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dongjoo Seo <commisori28@gmail.com>
|
@maobaolong @sammshen Could you take a look by any chance? |
|
@DongDongJu I left two comments previously :) |
I bliv that one was io_uring one. haha. isnt it? |
|
|
||
| raw = self._rawdev() | ||
|
|
||
| raw.pwrite_from_buffer(payload_off, payload, payload_len, payload_total_len) |
There was a problem hiding this comment.
checkpoint payload is written in-place (payload_off) before header commit. if the process/device crashes during that payload write, the previous payload is partially overwritten while the old header is still present. on restart CRC check fails and the loader drops metadata entirely so restart recovery can be lost after a single torn write.
There was a problem hiding this comment.
You are right. Thanks! I added the fix for this in here e76aa46
| shape_list = e.get("shape") | ||
| fmt_name = e.get("fmt") | ||
|
|
||
| offset = int(entry.get("offset", 0)) |
There was a problem hiding this comment.
offset/size from checkpoint entries are accepted without checking:
offset >= data_base_offset
slot alignment ((offset - data_base_offset) % slot_bytes == 0)
size > 0 and size <= slot_bytes - header_bytes
There was a problem hiding this comment.
Thanks! I added _is_valid_checkpoint_entry func.
|
my bad, I forgot to click "submit review", thx for the reminder! |
Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com>
|
It seems weird. wha is the latest patch touch cache engine? |
|
@deng451e Could you take a look by any chance? |
ApostaC
left a comment
There was a problem hiding this comment.
Some quick question, otherwise LGTM!
| return | ||
| return snapshot, dirty_total | ||
|
|
||
| def _write_checkpoint(self, payload: bytes, dirty_total_snapshot: int) -> bool: |
There was a problem hiding this comment.
Should we make this function being thread-safe? This will be called by _checkpoint_once, which will be called in both _checkpoint_loop and close
There was a problem hiding this comment.
Good catch.
The intended flow here is single-writer: close() stops the periodic checkpoint thread and joins it before issuing the final _checkpoint_once(force=True), so under the normal shutdown path _checkpoint_loop and close() should not overlap.
That said, relying on join(timeout=5) alone is a bit brittle, since it does not strictly guarantee the background thread has exited.
I agree it’s safer to serialize the checkpoint path explicitly. I’ll tighten this by guarding the checkpoint flow itself (likely at _checkpoint_once(), not only _write_checkpoint()), so the snapshot/write/seq update stays single-writer even during shutdown.
Next one is target to multi io worker. I will dealing this sync issue in next series.
Thanks for the review!
…tup (LMCache#2614) * feat(rust_raw_block): persist metadata on device and update recovery tests Replace file-manifest fallback with on-device metadata checkpoint handling and update rust raw block backend tests for the new recovery behavior and config surface. Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> * fix(benchmark): avoid truncating raw block devices under /dev Only create/truncate backing files for non-/dev paths so raw-device benchmark runs do not issue file truncate operations on block devices. Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> * rust_raw_block: harden metadata checkpoint slot validation - Validate next_slot/free_slots strictly when loading metadata - Deduplicate and range-check free slots - Avoid re-adding duplicate/invalid free slots in runtime paths - Ensure free list excludes slots already used by loaded index - Guard metadata region to require header + payload space Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> * fix style Signed-off-by: DongDongJu <commisori28@gmail.com> * Update lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dongjoo Seo <commisori28@gmail.com> * fix style Signed-off-by: DongDongJu <commisori28@gmail.com> * fix(raw-block): harden metadata checkpoint recovery Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> --------- Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <commisori28@gmail.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…tup (LMCache#2614) * feat(rust_raw_block): persist metadata on device and update recovery tests Replace file-manifest fallback with on-device metadata checkpoint handling and update rust raw block backend tests for the new recovery behavior and config surface. Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> * fix(benchmark): avoid truncating raw block devices under /dev Only create/truncate backing files for non-/dev paths so raw-device benchmark runs do not issue file truncate operations on block devices. Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> * rust_raw_block: harden metadata checkpoint slot validation - Validate next_slot/free_slots strictly when loading metadata - Deduplicate and range-check free slots - Avoid re-adding duplicate/invalid free slots in runtime paths - Ensure free list excludes slots already used by loaded index - Guard metadata region to require header + payload space Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> * fix style Signed-off-by: DongDongJu <commisori28@gmail.com> * Update lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dongjoo Seo <commisori28@gmail.com> * fix style Signed-off-by: DongDongJu <commisori28@gmail.com> * fix(raw-block): harden metadata checkpoint recovery Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> --------- Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com> Signed-off-by: DongDongJu <commisori28@gmail.com> Signed-off-by: Dongjoo Seo <commisori28@gmail.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>


What this PR does / why we need it:
This is needed to keep metadata colocated with raw block storage, simplify recovery semantics, and avoid invalid benchmark setup on real block devices.
If applicable: