6.3 KiB
RESUME POINT — cubefs FUSE <-> cube-server daemon durability wiring
Saved: 2026-08-13 (user paused session; pick up from here).
GOAL (from task list)
Make cubefs a real FUSE view of the running cube-server daemon's durable
store, and prove a FUSE write lands in the daemon WAL and survives a daemon
restart. (Cube-server is a pure command server — it does NOT mount FUSE
itself; the FUSE view is a separate cubefs-mount --socket process, per the
PDF/spec architecture.)
WHAT IS DONE (compiles + tests green)
- Raw-coordinate command family added to
cubesys/src/commands.rsdispatch:rawget <c> <z> <y> <x>,rawput <c> <z> <y> <x> <hex>,rawdel <c> <z> <y> <x>,rawkeys,rawscan <c> [z] [y]. Helpers added:parse_u8,hex_encode,hex_decode. (rawput/rawdel go through the durableConcurrentStoreso they hit the WAL.) cubefs/src/backend.rs— newDaemonBackendimplementingCubeBackendover the daemon Unix socket (lazy length-prefixed framing, duplicated fromcubesys::netto keep cubefs free of a cubesys dep). Registered incubefs/src/lib.rs(pub mod backend; pub use backend::DaemonBackend;).DaemonBackendis Clone (clones share socket path, reconnect lazily).cubefs/src/bin/cubefs_mount.rs—--socket PATHmounts against a live daemon; without--socketit falls back to an in-memoryHashBackend.cargo build --workspaceGREEN.cargo test --workspaceGREEN. (Note:DaemonBackendis NOT yet exercised by any unit/integration test — only manual host verification below.)
WHAT IS PROVEN (host-level, same kernel/code path as the VM)
A. Daemon durability + WAL replay: launched daemon with --store, rawput,
killed it with kill -9 (crash), relaunched same --store → rawget
returned the written value; recovery log showed
wal_recovery: applied 1. So the DAEMON half of the durability story works.
B. Direct rawput from a Python client checkpoints to store.json (4-byte
record appeared after the checkpoint interval). Confirmed daemon is alive,
reachable, and durable on the host.
WHAT IS BROKEN (the open bug) — RESOLVED 2026-08-13 (commit 0300def)
Two separate bugs hid behind the "FUSE write didn't reach the daemon" symptom:
-
--features mountdid not compile (E0308:CubeFs<DaemonBackend>vsCubeFs<HashBackend>are distinct types in thematch &socket). The build failed silently, so the running binary was the IN-MEMORY build and--socketwas ignored. FIXED in8f9e7e0by type-erasing the backend (Box<dyn CubeBackend + Send + Sync>+ a forwarding impl). -
Even after (1),
DaemonBackendround-tripped the WRONG layer:putstripped the record envelope to a bare body beforerawput, butgetreturned that bare body as if it were a full record — so the FUSE read-back path (get_record) could not decode it, and the socket backend diverged from the in-memory backend. FIXED in0300def:DaemonBackend::put/getnow round-trip the FULL envelope (header+body) verbatim through rawput/rawget, matching the in-memoryHashBackendexactly. This is now an enforced./check daemonintegration test (spins up a live cube-server, runs the two#[ignore]d daemon-backed tests via--ignored).
GATE STATUS (2026-08-13, end of session)
./check(fmt+test+clippy -D warnings) GREEN../check daemonGREEN — proves the socket-backed record round-trip against a real daemon (3 ignored tests via --ignored all pass)../check mount(live FUSE, root) GREEN — 27/27 pass. This is the regression guard exercising the real kernel VFS path; it now runs cleanly with the fixed durable-mount code. Run before any future filesystem work.
NEXT STEPS (current)
Repeat the single-daemon + single-mount e2e INSIDE the VM...DONE (see below).- Add a
--features mountbuild to the VM image's build step /./checkso the durable mount can't silently regress to in-memory again. (DONE on host ./check; VM image build step not yet updated.) - Optionally surface
DaemonBackend::putfailures as FUSE EIO instead of eprintln-only (best-effort today, acceptable). Confirm the desktop "CUBE Shell" launcher execsDONE 2026-08-13:cubec.../usr/share/applications/cube.desktop-> Exec/opt/cube/bin/cube-term, which exportsCUBE_SOCKET=/run/cube/cube.sockandexec /opt/cube/bin/cubec. The skill's #1 gotcha (must usecubec, notcube repl) is satisfied at the file level (not visually launched, per user instruction to not block on viewability).
COMPLETED THIS SESSION
- Fixed
DaemonBackendenvelope round-trip (commit0300def) — was returning the bare body instead of the full record envelope; the--socketmount could not read back FUSE writes. Fixed by round-tripping the full envelope verbatim. - Fixed
--features mountcompile break (commit8f9e7e0) —Czyxfield access. - Enforced BOTH bugs via
./check daemon(the two #[ignore]d integration tests now run via --ignored and would fail if either regressed). - Host:
./check+./check daemon+./check mountall GREEN. - VM (/var/lib/cubevm/cubelinux-vm.qcow2, was pre-fix): rebuilt cubefs-mount from
the fixed source, rewired cubefs.service to
--socket /run/cube/cube.sockwithRequires=cube-server.service, and proved a FUSE write survives a daemon restart (WAL persistence). Injected SSH key for cube+root to drive the VM. ./check also passes inside the VM (rustfmt+clippy components added).
KEY FILES
- /home/CUBELinux/CUBELinux-2/cubesys/src/commands.rs (raw* commands + helpers)
- /home/CUBELinux/CUBELinux-2/cubefs/src/backend.rs (DaemonBackend — FIX HERE)
- /home/CUBELinux/CUBELinux-2/cubefs/src/lib.rs (module export)
- /home/CUBELinux/CUBELinux-2/cubefs/src/bin/cubefs_mount.rs (--socket wiring)
- /home/CUBELinux/CUBELinux-2/cubestore/src/lib.rs (CubeStore::put_raw L358)
- /home/CUBELinux/CUBELinux-2/cubefs/src/vfs.rs (CubeFs::write L392)
TEST HARNESS NOTES
- Launch daemon/mount as
terminal(background=true)so Hermes tracks them. - A
python3one-shot client for rawget/rawput: socket connect, sendall(struct.pack('<I',len(payload))+payload), read 4-byte len then body. - Daemon flags used:
--socket S --store STORE.json --recovery-log REC.ndjson --allow-anonymous --checkpoint-ms 400 --wal-fsync-ms 30