Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SwiftFuse 深度检测流程(12-Gate)

版本:2026-08-08 · 与 docs/REPORT-2026-08-08.md(检测报告)配套 原则:结果如实记录 —— 每个 gate 输出 PASS / FAIL / INCONCLUSIVE / NOT SUPPORTED, 绝不假装通过。KNOWN DEVIATION 与声明限制分开记录。


0. 检测体系总览

                           SwiftFuse Test System (12 gates)

         Correctness               Distributed               Performance
   G1  pjdfstest (POSIX)     G6  多客户端一致性         G8  fio 矩阵 + mdtest
   G2  fstests generic      G7  故障注入 (etcd/tc)      G9  Filebench
   G3  LTP syscall          G10 1→2→4 节点 scale       G12 IO500/SPECstorage*
   G4a fsx                  G11 可复现性 (env/tag/raw)
   G4b fio verify+SIGKILL
   G5  fsstress
  • *G12:IO500 需多节点 MPI 集群(lab 4×8GB 不满足 → NOT SUPPORTED); SPECstorage 2020 需商业 license($2,000)→ NOT SUPPORTED。
  • 单节点跑 G1-G5、G7、G8、G9、G11;G6/G10 需要 swift2-4 可达。

1. 运行方法

# 在 swift1 上(检测工具已装好)
/opt/detect/run_gates.sh /mnt/swift-etcd /opt/detect/results/$(date +%s)

# 等价于仓库镜像(同步到节点后):
/opt/swiftfuse/scripts/detect/run_gates.sh /mnt/swift-etcd /opt/detect/results/$(date +%s)

前置条件

  1. deploy_cluster.sh 已全节点部署(代码 = 当前 master HEAD,config 含 kernel_ttl = 0)。
  2. 工具链在 swift1:/opt/detect/bin/{fsx,fsstress}、/opt/detect/src/pjdfstest、 (可选)/opt/detect/src/{fstests,ltp}、mdtest、filebench。
  3. 挂载存活:mount | grep /mnt/swift-etcd。

产物结构

$R/  (如 /opt/detect/results/20260808-203000)
├── environment.txt      # G11: kernel/commit/tag/mount/config/df
├── results.tsv          # 逐 gate: gate<TAB>case<TAB>verdict<TAB>detail
├── summary.txt          # 汇总
├── perf-summary.txt     # G8 性能值
├── errors.log           # FAIL 时附加的证据
├── gate.log             # 时间戳流水
└── g1..g10/             # 每 gate 原始产物(prove/fio/fsx/…)

2. Gate 明细

Gate工具方法判定规则
G1pjdfstest在挂载点内 prove -r 全量失败文件分类:symlink/link/mkfifo/mknod* → UNSUPPORTED(ARCHITECTURE.md 声明 ENOSYS);utimensat/05 → KNOWN DEVIATION;其余 → FAIL
G2fstests (xfstests)check -f fuse curated generic/001-100FUSE 非块设备 FS,大量 generic 用例 NOT SUPPORTED(mkfs/scratch/reflink);PASS/FAIL/NOT RUN 计数
G3LTPrunltp -f runtest/syscalls -s '^(stat|rename|unlink|…)'只跑文件系统相关 syscall 子集
G4afsx3 轮 × 2000 ops(16MiB 文件)退出码 0 = PASS
G4bfio verify64MiB 4K crc32c 写+verify;SIGKILL daemon → remount → verify_onlyverify 通过 = committed data 完好
G5fsstress4 proc × 200 ops无 panic/segfault 且有实际 ops = PASS;无 ops = INCONCLUSIVE
G6自研 harness本地 4 线程并发 append(size 单调不减)+ 50 rename + readdir 去重;swift2/3 远程并发写全部断言过 = PASS
G7故障注入a) etcd move-leader + verify;b) tc netem 5% 丢包+100ms×45s 内 fio write+verify;c) SIGKILL(=G4b 交叉引用)verify 数据完好
G8fio 矩阵 + mdtest4K/64K/1M × QD1/8/32 × seq/rand;mdtest 500 文件×3 轮 create/stat/removefio 产出 JSON;mdtest 有统计输出
G9filebenchfileserver 模型 30s有 IO Summary 输出
G10多节点1→2→4 节点并发 dd 32MiB/节点记录 nodes/files/dur/bw 曲线
G11可复现性environment.txt 记录 commit/tag/config/raw JSON每次运行自动产出
G12IO500/SPECstorage—NOT SUPPORTED(lab 资源/商业 license),附条件与路线

3. 手工复现命令(单测 / 回归)

# 快速 rename-over-existing 回归(BUG-2)
cd /mnt/swift-etcd && echo BBB > t && echo AAA > s && mv s t && cat t   # 期望 AAA

# open-unlinked 回归(BUG-5)
python3 - <<'EOF'
import os
p = "/mnt/swift-etcd/od.bin"
fd = os.open(p, os.O_CREAT|os.O_RDWR, 0o644)
os.write(fd, b"x"*4096); os.fsync(fd)
os.unlink(p)
assert os.path.exists(p) is False            # 名字已消失
st = os.fstat(fd); assert st.st_nlink == 0   # nlink=0
os.write(fd, b"y"*100); os.fsync(fd)         # 写仍可用
assert os.read(fd, 10) == b""                # 读到 EOF
os.close(fd)                                 # 最后 fd 关闭 → 真正回收
print("open-unlinked OK")
EOF

# pjdfstest 单目录
mkdir -p /mnt/swift-etcd/pjd && cd /mnt/swift-etcd/pjd && prove -r /opt/detect/src/pjdfstest/tests

# fsx / fsstress(G4a/G5 单跑)
/opt/detect/bin/fsx -q -N 2000 -P /tmp -c 65536 -l 16777216 /mnt/swift-etcd/fsxfile
/opt/detect/bin/fsstress -d /mnt/swift-etcd/stress -n 200 -p 4

# 单元测试(节点上)
cd /opt/swiftfuse && cargo test --workspace

4. 教训与注意事项(历史)

  1. pjdfstest 必须在挂载点内跑 —— 曾误在本地 XFS 跑出假绿(HANDOFF G1)。
  2. fio 不要用 sync=1 + 4K —— 每次写变成 block PUT,一轮数小时。
  3. G6 并发写断言不能用精确 size —— 写序未定义,用单调不减。
  4. G4b 的 SIGKILL 必须用 -9 —— 优雅退出会正常 flush,测不到崩溃恢复。
  5. fstests 对 FUSE 有大量 N/A —— 用 curated 子集 + NOT RUN 矩阵,不追求全绿。
  6. fstests 的 mount/unmount 工作流无法驱动单 daemon FUSE 挂载(2026-08-09)—— _test_mount 会对 TEST_DEV 二次 mount -t fuse;判定必须要求“实际执行了测试“ (0 测试执行 = NOT SUPPORTED,不是 PASS)。
  7. G6 脚本必须自清理(2026-08-09)—— 残留 cc-/rn-/rdir-* 会在下一轮被打开, 叠加 lease 语义制造假 FAIL。
  8. lease 断言区分同 holder 重入与跨 holder 拒绝(2026-08-09)—— 同进程重开同文件 是重入(成功),不是 EBUSY;跨 holder 拒绝需多 daemon 或注入测试。
  9. smoke 的 rename+truncate 是 BUG-7 哨兵(2026-08-09)—— rename 后任意新目录条目 创建会暴露 bridge nodeid 复用;smoke 9/9 是回归底线。

5. 路线图(未落地项)

  • G2/G3 全量:xfstests 全 generic + LTP 全 syscall(需更稳的构建链与专用测试盘)。
  • G7 增强:etcd 成员 kill(非 leader)、Swift proxy 重启注入、双节点网络分区。
  • G12 IO500:需要 ≥4 节点 × ≥64GB + InfiniBand/万兆网络 + MPI 集群。
  • JSepsen 式线性一致性检查:Rust harness → JSON history → Porcupine checker (现 G6 为轻量版,G6 论文级版本见路线)。
  • doc site:本期只同步 Google Drive;doc site(如 nginx @ swift1)列入后续。