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.
60 lines
3.5 KiB
Markdown
60 lines
3.5 KiB
Markdown
# 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)
|