Files
zvfs/plan/plan.md

11 KiB
Raw Blame History

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 最小集合”和“当前实现缺口表”。

任务

  • strace 或等效方式采集 db_bench syscall含失败分支
  • 形成兼容矩阵:必须实现 / 可降级透传 / 暂不支持。
  • 固化第一批验收用例(最小 db_bench 参数 + 现有单测集合)。

交付物

  • plan/rocksdb_syscall_matrix.md
  • plan/baseline_commands.md

阶段验收

  • 能明确列出阶段2必须完成的 hook 列表。

正确性验证方案

  • 验证矩阵中的每个“必须实现 syscall”都有最小复现样例命令或小程序
  • 基线命令可重复执行,输出包含 syscall 统计与错误码分布。
  • 验证结果记录到 plan/baseline_commands.md(含日期和环境信息)。

阶段1架构解耦关键

目标

  • 把 I/O 请求参数从 zvfs_file_t 中拆出,建立请求对象,先打通 pread/pwrite 内核路径。

任务

  • 新增 zvfs_io_req字段至少op/buf/len/offset/flags/result/errno/finished
  • 重构 zvfs_read/zvfs_write 为基于 zvfs_io_req 的通用入口。
  • 实现内部 zvfs_pread_internal/zvfs_pwrite_internal,不改 hook 先可调用。
  • 移除 zvfs_file_t 中仅一次请求有效的临时字段(或标记弃用)。

交付物

  • zvfs/zvfs.h 新结构与接口
  • zvfs/zvfs.c 读写路径重构完成
  • plan/phase1_validation.md(用户侧验证步骤)

阶段验收

  • 现有 read/write/lseek 测试全通过。
  • 新增 pread/pwrite 单测通过(可先直连接口,不经 hook

正确性验证方案

  • 新旧接口结果一致性校验:同一输入下 read/writepread/pwrite 数据一致。
  • 边界测试offset=0、EOF、跨 page、非对齐、空写入。
  • 失败路径测试:非法 fd/参数时返回值与 errno 符合预期。

阶段2补齐 hook 与 POSIX 语义

目标

  • 满足 RocksDB 最小兼容 API 集,保证语义与 errno 正确。

首批必须实现

  • pread/pwrite(及 pread64/pwrite64 视平台符号而定)
  • open/open64/openat
  • fsync/fdatasync
  • ftruncate
  • fstat/stat/lstat(至少满足 RocksDB 元数据查询)
  • rename(原子替换语义)

语义修复

  • open 支持 O_TRUNC/O_APPEND/O_EXCL
  • 权限检查(O_RDONLY/O_WRONLY/O_RDWR
  • 返回值与 errno 映射统一(失败路径不可吞错)

交付物

  • zvfs/zvfs_hook.cphase2 hook 覆盖与语义修复)
  • test/test_phase2_posix.cphase2 POSIX 回归用例)
  • 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 变更记录(按时间追加)

  • 2026-03-02: 完成 phase0db_bench syscall 基线 + 失败分支 + 兼容矩阵);文件:plan/plan.mdplan/rocksdb_syscall_matrix.mdplan/baseline_commands.md;风险:当前环境 SPDK 初始化失败IOVA PA 不可用),需在 phase1 前确定运行环境策略
  • 2026-03-02: 完成 phase1 代码改造file/io_req 解耦 + 新增 pread/pwrite API文件zvfs/zvfs.hzvfs/zvfs.cplan/plan.mdplan/phase1_validation.md;风险:本轮未在 root+LD_PRELOAD 环境完成端到端验证
  • 2026-03-02: 根据用户反馈修复 phase1 边界问题preread 失败时将临时缓冲区清零,避免洞区读到脏数据);文件:zvfs/zvfs.cplan/phase1_validation.md;风险:仍需用户侧端到端复测确认
  • 2026-03-02: 根据用户复测继续修复 sparse hole 问题offset>EOF 时清零本次覆盖页内 gap 区间);文件:zvfs/zvfs.cplan/plan.md;风险:跨多页大洞写入语义仍需在 phase2 做专项覆盖
  • 2026-03-02: 完成 phase2 代码改造(补齐 openat/pread/pwrite/fsync/ftruncate/stat/rename/fcntl/mkdir/rmdir 等 hook 与关键语义);文件:zvfs/zvfs_hook.czvfs/zvfs.htest/test_phase2_posix.ctest/Makefileplan/phase2_validation.mdplan/plan.md;风险:尚未在用户环境完成 db_bench 端到端验收
  • 2026-03-02: 根据用户 db_bench 反馈修复目录打开语义(目录允许 O_RDONLY 打开,不再强制要求 O_DIRECTORY文件zvfs/zvfs_hook.c;风险:仍需用户复测 db_bench
  • 2026-03-02: 根据用户 db_bench 反馈补齐 fadvise/fallocate/sync_file_range hook避免 pseudo-fd 被内核路径误判为 EBADF文件zvfs/zvfs_hook.czvfs/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 语义测试通过并有失败用例说明
  • 文档包含部署方式、限制项、回归命令