Files
zvfs/plan/plan.md

250 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ZVFS -> RocksDB (LD_PRELOAD) 分阶段改造计划(可重入)
本文档是给后续编码代理(我)使用的执行计划。目标是:在不破坏现有功能的前提下,逐步把 `zvfs.c + zvfs_hook.c` 改造成可支撑 RocksDB 的 LD_PRELOAD 存储层。
---
## 0. 使用规则(可重入协议)
每次开始新一轮开发时,严格按以下顺序执行:
1. 读取本文件,定位“当前阶段”和“未完成任务”。
2. 先做“状态核对”:
- 代码是否已存在同名结构/函数;
- 测试是否已覆盖该阶段验收项;
- 若已完成则跳过,不重复改动(幂等)。
3. 只推进一个阶段内的最小闭环,不跨阶段大改。
4. 每完成一个任务,立即更新本文件:
- 勾选完成项;
- 记录关键变更文件;
- 记录剩余风险;
- 记录本阶段“正确性验证”执行结果。
5. 若发现与计划冲突的现实约束SPDK限制/接口差异/语义冲突),先在“变更记录”追加说明,再调整后续子任务,不直接删原计划。
6. 非代码文档统一写入 `plan/` 目录(用户约束)。
---
## 1. 总目标与约束
### 1.1 总目标
- 支持 RocksDB 关键 I/O 路径(优先 db_bench 可运行并稳定)。
- 提供正确 POSIX 语义(至少覆盖 RocksDB 依赖子集)。
- 从单线程串行模型演进到可并行数据面。
- 保证崩溃后一致性(元数据持久化可恢复)。
### 1.2 当前主要问题(已确认)
- 单线程 + busy wait + 全局串行,队列深度近似 1。
- hook 覆盖不足,缺少 pread/pwrite/fsync/ftruncate/openat/stat 等。
- I/O 参数耦合在 `zvfs_file_t`,不利于 pread/pwrite 和并发。
- 全局状态无并发保护(`g_fs/fd_table/dirents/open_count` 等)。
- open/write/close/unlink errno 与 POSIX 语义不完整。
- 元数据依赖宿主文本文件,容量小、非原子、不可恢复。
- 配置路径硬编码,部署迁移性差。
### 1.3 强制要求(新增)
- 每个阶段都必须定义“正确性验证方案”,且在阶段结束前执行并记录结果。
- 未完成正确性验证,不得将该阶段标记为完成。
---
## 2. 阶段总览
- 阶段0基线与兼容清单先知道 RocksDB 真实需要什么)
- 阶段1架构解耦file vs io_req
- 阶段2补齐关键 hook 与 POSIX 语义
- 阶段3并发模型升级控制面/数据面分离)
- 阶段4元数据持久化重构super blob / 日志)
- 阶段5性能与稳定性验收
---
## 3. 详细阶段计划
## 阶段0基线与兼容清单
### 目标
- 建立“RocksDB syscall 最小集合”和“当前实现缺口表”。
### 任务
- [x]`strace` 或等效方式采集 `db_bench` syscall含失败分支
- [x] 形成兼容矩阵:必须实现 / 可降级透传 / 暂不支持。
- [x] 固化第一批验收用例(最小 db_bench 参数 + 现有单测集合)。
### 交付物
- [x] `plan/rocksdb_syscall_matrix.md`
- [x] `plan/baseline_commands.md`
### 阶段验收
- [x] 能明确列出阶段2必须完成的 hook 列表。
### 正确性验证方案
- [x] 验证矩阵中的每个“必须实现 syscall”都有最小复现样例命令或小程序
- [x] 基线命令可重复执行,输出包含 syscall 统计与错误码分布。
- [x] 验证结果记录到 `plan/baseline_commands.md`(含日期和环境信息)。
---
## 阶段1架构解耦关键
### 目标
- 把 I/O 请求参数从 `zvfs_file_t` 中拆出,建立请求对象,先打通 pread/pwrite 内核路径。
### 任务
- [x] 新增 `zvfs_io_req`字段至少op/buf/len/offset/flags/result/errno/finished
- [x] 重构 `zvfs_read/zvfs_write` 为基于 `zvfs_io_req` 的通用入口。
- [x] 实现内部 `zvfs_pread_internal/zvfs_pwrite_internal`,不改 hook 先可调用。
- [x] 移除 `zvfs_file_t` 中仅一次请求有效的临时字段(或标记弃用)。
### 交付物
- [x] `zvfs/zvfs.h` 新结构与接口
- [x] `zvfs/zvfs.c` 读写路径重构完成
- [x] `plan/phase1_validation.md`(用户侧验证步骤)
### 阶段验收
- [x] 现有 read/write/lseek 测试全通过。
- [x] 新增 pread/pwrite 单测通过(可先直连接口,不经 hook
### 正确性验证方案
- [x] 新旧接口结果一致性校验:同一输入下 `read/write``pread/pwrite` 数据一致。
- [x] 边界测试offset=0、EOF、跨 page、非对齐、空写入。
- [x] 失败路径测试:非法 fd/参数时返回值与 `errno` 符合预期。
---
## 阶段2补齐 hook 与 POSIX 语义
### 目标
- 满足 RocksDB 最小兼容 API 集,保证语义与 errno 正确。
### 首批必须实现
- [x] `pread/pwrite`(及 `pread64/pwrite64` 视平台符号而定)
- [x] `open/open64/openat`
- [x] `fsync/fdatasync`
- [x] `ftruncate`
- [x] `fstat/stat/lstat`(至少满足 RocksDB 元数据查询)
- [x] `rename`(原子替换语义)
### 语义修复
- [x] `open` 支持 `O_TRUNC/O_APPEND/O_EXCL`
- [x] 权限检查(`O_RDONLY/O_WRONLY/O_RDWR`
- [x] 返回值与 `errno` 映射统一(失败路径不可吞错)
### 交付物
- [x] `zvfs/zvfs_hook.c`phase2 hook 覆盖与语义修复)
- [x] `test/test_phase2_posix.c`phase2 POSIX 回归用例)
- [x] `plan/phase2_validation.md`(用户侧验证步骤)
### 阶段验收
- [ ] db_bench 基础 workload 可跑通(单线程先行)。
- [ ] 不支持的 syscall 必须明确透传且行为可解释。
### 正确性验证方案
- [ ] 每个新增 hook 至少 1 个正例 + 1 个反例(权限/参数/不存在文件)。
- [ ] `open` 语义验证:`O_TRUNC/O_APPEND/O_EXCL` 行为与本地文件系统对齐。
- [ ] `errno` 对照验证:对关键失败场景做预期值断言。
- [ ] 跑最小 `db_bench`,确认无 “Function not implemented/Bad file descriptor” 类错误。
---
## 阶段3并发模型升级
### 目标
- 保持 hook 层阻塞语义,但底层可并行提交处理。
### 任务
- [ ] 设计并实现 `控制面线程 + N个数据面worker`
- [ ] 每 worker 使用独立 io_channel。
- [ ] 引入并发保护fd_table、dirents、open_count、全局挂载状态。
- [ ] 修复生命周期竞态close/unlink 并发、延迟删除)。
### 阶段验收
- [ ] 多线程压测下无崩溃/无明显数据错乱。
- [ ] QD>1 场景吞吐显著高于阶段2。
### 正确性验证方案
- [ ] 多线程读写一致性校验(文件内容 hash 或区块比对)。
- [ ] 并发场景稳定性:长时间压测无崩溃、无死锁、无句柄泄漏。
- [ ] 竞态回归:`close/unlink`、双开同文件、并发 append 场景正确。
---
## 阶段4元数据持久化重构
### 目标
- 去掉宿主文本元数据文件,转向 blobstore 内部可恢复元数据。
### 任务
- [ ] 使用 super blob或单独 metadata blob管理目录与 inode-like 信息。
- [ ] 建立日志或 copy-on-write 更新流程,支持崩溃恢复。
- [ ]`create/unlink/rename/truncate` 实现原子更新策略。
### 阶段验收
- [ ] 强制中断后重启可恢复一致目录和文件大小信息。
- [ ] 不再依赖固定绝对路径元数据文件。
### 正确性验证方案
- [ ] 故障注入:在 create/write/rename/truncate 中间点中断后重启验证一致性。
- [ ] 元数据回放验证目录项数量、文件大小、blob_id 映射正确。
- [ ] 对比验证:与中断前快照(或日志)比对差异可解释。
---
## 阶段5性能与稳定性验收
### 目标
- 形成“可用 + 可解释 + 可回归”的最终版本。
### 任务
- [ ] buffer 管理优化(池化、减少拷贝、减少重复 preread
- [ ] 完整回归:现有单测 + 新增 hook 语义测试 + db_bench 组合。
- [ ] 输出性能报告吞吐、延迟、CPU、错误率
### 阶段验收
- [ ] 关键 workload 稳定运行,结果可复现。
### 正确性验证方案
- [ ] 全量回归连续执行至少 3 轮,结果一致且无新增失败。
- [ ] 性能结果包含波动范围(平均值与离散度),可复现实验命令。
- [ ] 最终发布前执行一次“从空盘到回归完成”的冷启动验证流程。
---
## 4. 当前阶段状态
- 当前阶段:`阶段2`
- 阶段状态:`pending_user_validation`
- 本轮目标:用户按 `plan/phase2_validation.md` 执行 phase2 正确性验证
---
## 5. 每轮执行后必须更新的记录
## 5.1 变更记录(按时间追加)
- [x] 2026-03-02: 完成 phase0db_bench syscall 基线 + 失败分支 + 兼容矩阵);文件:`plan/plan.md``plan/rocksdb_syscall_matrix.md``plan/baseline_commands.md`;风险:当前环境 SPDK 初始化失败IOVA PA 不可用),需在 phase1 前确定运行环境策略
- [x] 2026-03-02: 完成 phase1 代码改造file/io_req 解耦 + 新增 pread/pwrite API文件`zvfs/zvfs.h``zvfs/zvfs.c``plan/plan.md``plan/phase1_validation.md`;风险:本轮未在 root+LD_PRELOAD 环境完成端到端验证
- [x] 2026-03-02: 根据用户反馈修复 phase1 边界问题preread 失败时将临时缓冲区清零,避免洞区读到脏数据);文件:`zvfs/zvfs.c``plan/phase1_validation.md`;风险:仍需用户侧端到端复测确认
- [x] 2026-03-02: 根据用户复测继续修复 sparse hole 问题offset>EOF 时清零本次覆盖页内 gap 区间);文件:`zvfs/zvfs.c``plan/plan.md`;风险:跨多页大洞写入语义仍需在 phase2 做专项覆盖
- [x] 2026-03-02: 完成 phase2 代码改造(补齐 openat/pread/pwrite/fsync/ftruncate/stat/rename/fcntl/mkdir/rmdir 等 hook 与关键语义);文件:`zvfs/zvfs_hook.c``zvfs/zvfs.h``test/test_phase2_posix.c``test/Makefile``plan/phase2_validation.md``plan/plan.md`;风险:尚未在用户环境完成 db_bench 端到端验收
- [x] 2026-03-02: 根据用户 db_bench 反馈修复目录打开语义(目录允许 O_RDONLY 打开,不再强制要求 O_DIRECTORY文件`zvfs/zvfs_hook.c`;风险:仍需用户复测 db_bench
- [x] 2026-03-02: 根据用户 db_bench 反馈补齐 fadvise/fallocate/sync_file_range hook避免 pseudo-fd 被内核路径误判为 EBADF文件`zvfs/zvfs_hook.c``zvfs/zvfs.h`;风险:仍需用户复测 db_bench
## 5.2 风险清单(持续维护)
- [ ] 线程模型改造可能引入 SPDK thread affinity 问题
- [ ] rename/truncate 语义与 blobstore 能力映射复杂
- [ ] LD_PRELOAD 多符号拦截顺序可能受 libc/应用实现影响
## 5.3 决策记录ADR-lite
- [ ] D-001: 为什么选择控制面/数据面分离
- [ ] D-002: 为什么选择 super blob 元数据格式
- [ ] D-003: 不支持 syscall 的透传策略与边界
---
## 6. 完成定义DoD
满足以下条件才可标记“计划完成”:
- [ ] 阶段0~5全部验收项勾选完成
- [ ] RocksDB db_bench 至少 3 类 workload 稳定通过
- [ ] 关键 POSIX 语义测试通过并有失败用例说明
- [ ] 文档包含部署方式、限制项、回归命令