Files
cubelinux-2/VERIFICATION-cubefs-daemon.md
CUBELinux-2 8f9e7e0025 fix(cubefs): make FUSE mount a durable view of cube-server daemon store
The cubefs-mount --socket path was never actually built: CubeFs<B> is
generic, so the --socket (DaemonBackend) and default (HashBackend) arms
of the match were incompatible types (E0308), and --features mount failed
to compile. The running binary was therefore the in-memory build, so
--socket was silently ignored and every FUSE write went to RAM and never
reached the daemon (rawget/rawkeys returned none / 0 keys, WAL stayed 0).

Fix: type-erase the backend. Add  (forwards to inner) in cubestore, and build
 in cubefs-mount via
Box::new(DaemonBackend::new(p)) / Box::new(HashBackend::new()). Keeps
cubefs free of a cubesys dep (acyclic graph).

Verified end-to-end on host (shared code path as the VM): a FUSE write
via  lands in the daemon store (rawget returns the
record, 5 keys present, WAL grows), and survives a  of the
daemon + relaunch with the same --store (byte-identical read-back).

Also includes (from RESUME-cubefs-daemon.md): cubesys raw* command family
(rawget/rawput/rawdel/rawkeys/rawscan + parse/hex helpers) and the
DaemonBackend client + smoke tests. Report/verification docs added.

Note: VM cubefs.service still mounts in-memory (no --socket); update the
unit to  as a
follow-up so the deployed VM FUSE is durable too.
2026-08-13 05:40:59 -04:00

3.5 KiB

VERIFICATION: cubefs FUSE view <-> cube-server daemon durability (REVISED 2026-08-13)

Hard record for later review. Date: 2026-08-13 (session after restart).

Critical correction to the prior version of this file

The earlier "proof" in this file was measured against CubeFs DIRECTLY (cubefs_daemon_smoke test calling fs.create+fs.write on a CubeFs<DaemonBackend>), NOT against the actual cubefs-mount --socket FUSE binary. The FUSE binary (cubefs-mount) requires --features mount to build, and at that time it did NOT compile: CubeFs<B> is generic, so the --socket (DaemonBackend) and default (HashBackend) arms were incompatible types (E0308). The build was silently failing, so the running cubefs-mount was the IN-MEMORY build — which is why --socket was ignored and every FUSE write went to RAM and never reached the daemon (rawget/rawkeys returned none / 0 keys, WAL stayed 0 bytes). The prior "proof" therefore did NOT verify the FUSE mount.

The actual bug that blocked durable FUSE (now FIXED)

  • cubefs/src/bin/cubefs_mount.rs: the match &socket produced CubeFs<DaemonBackend> vs CubeFs<HashBackend> — incompatible; --features mount failed to compile (E0308), so the durable mount was never shippable.
  • Fix: type-erase the backend. Added impl CubeBackend for Box<dyn CubeBackend + Send + Sync> (forwards to inner) in cubestore/src/lib.rs, and changed the mount to build CubeFs<Box<dyn CubeBackend + Send + Sync>> via Box::new(DaemonBackend::new(p)) / Box::new(HashBackend::new()). Both arms are now the same concrete type; --features mount compiles.
  • This keeps cubefs free of a cubesys dependency (DaemonBackend duplicates the framing locally), so the dependency graph stays acyclic.

Proof the FUSE mount reaches the daemon AND survives a crash (REAL, this run)

Harness: bash /tmp/verify_cubefs_daemon_host.sh (daemon + one mount, both on the same socket, then kill -9 daemon and relaunch).

  1. mkdir -p /tmp/verify/mnt/c012/z003/y004
  2. echo cubefs-e2e-proof-<ts> > /tmp/verify/mnt/c012/z003/y004/x007
  3. FUSE read-back returns cubefs-e2e-proof-<ts> (write visible through FUSE).
  4. Daemon rawget 12 3 4 7 -> ok: <record hex>; rawkeys -> ok: 5 keys (volume meta + the new record landed in the daemon store).
  5. cube-store.json.wal grew to 956 bytes (durable WAL written).
  6. kill -9 the daemon, relaunch with the same --store.
  7. Post-crash rawget 12 3 4 7 returns the SAME record bytes; post-crash FUSE read-back returns cubefs-e2e-proof-<ts>. Survived the daemon crash.

Decoded body of the rawget record: cubefs-e2e-proof-1786613763 — byte-exact match to what was written through the FUSE mount.

Conclusion

cubefs is now a genuine FUSE view of the running cube-server daemon's durable store, and a FUSE write lands in the daemon WAL and survives a daemon restart. The "cubefs as boot-time data root" integration is functionally proven on the host (shared code path as the VM). Next: repeat the same single-daemon + single-mount e2e INSIDE the VM to confirm the deployed artifact, then wire --socket into the VM's cubefs.service (currently it mounts without --socket, i.e. in-memory — that is why the VM FUSE looked like it worked but never persisted to the daemon).

Test files

  • cubefs/tests/cubefs_daemon_smoke.rs (CubeFs+DaemonBackend, needs live daemon via CUBE_SOCK)
  • cubefs/tests/daemon_backend_smoke.rs (DaemonBackend put/get/keys, needs live daemon)
  • /tmp/verify_cubefs_daemon_host.sh (full FUSE mount e2e on host)