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.
This commit is contained in:
@@ -99,6 +99,28 @@ impl CubeBackend for HashBackend {
|
||||
}
|
||||
}
|
||||
|
||||
/// Type-erased backend: lets `CubeFs`/`CubeStore` hold either a `HashBackend`
|
||||
/// or a `DaemonBackend` behind one concrete type, so callers (e.g.
|
||||
/// `cubefs-mount`, which chooses the backend at runtime from `--socket`) don't
|
||||
/// have to be generic over `B`. Forwards every call to the inner backend.
|
||||
impl CubeBackend for Box<dyn CubeBackend + Send + Sync> {
|
||||
fn put(&mut self, key: Czyx, value: Vec<u8>) {
|
||||
(**self).put(key, value)
|
||||
}
|
||||
fn get(&self, key: &Czyx) -> Option<Vec<u8>> {
|
||||
(**self).get(key)
|
||||
}
|
||||
fn delete(&mut self, key: &Czyx) {
|
||||
(**self).delete(key)
|
||||
}
|
||||
fn keys(&self) -> Vec<Czyx> {
|
||||
(**self).keys()
|
||||
}
|
||||
fn scan_prefix(&self, c: u8, z: Option<u8>, y: Option<u8>) -> Vec<Czyx> {
|
||||
(**self).scan_prefix(c, z, y)
|
||||
}
|
||||
}
|
||||
|
||||
/// A record store: a header + body addressed by a [`Czyx`] label.
|
||||
///
|
||||
/// Decision: we serialize the header and body as a single byte buffer with a
|
||||
|
||||
Reference in New Issue
Block a user