Volume replication groundwork (Phase 6 hardening plan):
- UDS handler: Add Store opcode (0x02) with opcode-based dispatch,
StoreRequest/StoreResponse wire types, and size validation
- storage/store.go: AppendRawNeedle() for accepting pre-serialized
needle bytes from RDMA replication path
- storage/needle: Return raw bytes from needle Append() to enable
forwarding exact .dat bytes without re-serialization
- storage/sra_transport.go: UDS client for outbound RDMA replication
(connects to /tmp/sra-transport.sock, nil-safe fallback to HTTP)
- command/volume.go: Wire -uds.transport flag
- Integration test for Store opcode round-trip
- Golden wire tests for Store request/response encoding
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add golden byte fixtures for LocateRequest and LocateResponse that must
match the Rust sra-volume side exactly. Also add needle endianness
contract test documenting that SeaweedFS uses big-endian for all
multi-byte needle fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Go server was parsing fid at bytes 0-15 (Go format), but Rust
uds_client sends opcode(1)+pad(3)+request_id(4)+fid(16) per
sra-common::uds_proto::LocateRequest repr(C).
Now Go parses: opcode at byte 0, request_id at bytes 4-7, fid at
bytes 8-23. Matches the Rust wire format exactly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add DatPathLen (2 bytes at offset 24) + variable-length DatPath after
the 32-byte header. Solves the filename mismatch where sra-volume
assumed {vol}.dat but SeaweedFS uses {collection}_{vol}.dat.
Backward compatible: old clients that only read 32 bytes still work
(DatPathLen is in the formerly-reserved region, and the trailing
path bytes are simply ignored by old readers).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent nil pointer dereference when VolumeServer is nil by adding
an early return with UdsStatusError before accessing vs.store.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>