mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-22 07:06:51 +00:00
feat(uds): include .dat file path in locate response
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>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
c1c73b0a5d
commit
cc634da5bd
@@ -15,8 +15,9 @@ import (
|
||||
|
||||
// UDS protocol constants
|
||||
const (
|
||||
UdsRequestSize = 24 // fid(16) + version(4) + flags(4)
|
||||
UdsResponseSize = 32 // status(1) + pad(3) + volume_id(4) + offset(8) + length(8) + reserved(8)
|
||||
UdsRequestSize = 24 // fid(16) + version(4) + flags(4)
|
||||
UdsResponseSize = 32 // status(1) + pad(3) + volume_id(4) + offset(8) + length(8) + dat_path_len(2) + reserved(6)
|
||||
UdsMaxDatPathLen = 256 // max .dat file path length
|
||||
)
|
||||
|
||||
// UDS status codes
|
||||
@@ -43,12 +44,14 @@ type LocateRequest struct {
|
||||
|
||||
// LocateResponse represents a UDS locate response
|
||||
type LocateResponse struct {
|
||||
Status uint8
|
||||
_pad [3]byte
|
||||
VolumeId uint32
|
||||
Offset uint64
|
||||
Length uint64
|
||||
_ [8]byte // reserved
|
||||
Status uint8
|
||||
_pad [3]byte
|
||||
VolumeId uint32
|
||||
Offset uint64
|
||||
Length uint64
|
||||
DatPathLen uint16 // length of .dat file path (follows the 32-byte header)
|
||||
_ [6]byte // reserved
|
||||
DatPath string // variable-length .dat file path (not in wire header)
|
||||
}
|
||||
|
||||
// NewUdsServer creates a new UDS server for the volume server
|
||||
@@ -142,7 +145,7 @@ func (u *UdsServer) handleConnection(conn net.Conn) {
|
||||
// Handle request
|
||||
resp := u.handleLocate(&req)
|
||||
|
||||
// Serialize response
|
||||
// Serialize response header (32 bytes)
|
||||
respBuf[0] = resp.Status
|
||||
respBuf[1] = 0
|
||||
respBuf[2] = 0
|
||||
@@ -150,13 +153,22 @@ func (u *UdsServer) handleConnection(conn net.Conn) {
|
||||
binary.LittleEndian.PutUint32(respBuf[4:8], resp.VolumeId)
|
||||
binary.LittleEndian.PutUint64(respBuf[8:16], resp.Offset)
|
||||
binary.LittleEndian.PutUint64(respBuf[16:24], resp.Length)
|
||||
// reserved bytes 24-32 are zero
|
||||
binary.LittleEndian.PutUint16(respBuf[24:26], resp.DatPathLen)
|
||||
// reserved bytes 26-32 are zero
|
||||
|
||||
// Write response
|
||||
// Write fixed header
|
||||
if _, err := conn.Write(respBuf); err != nil {
|
||||
glog.V(2).Infof("UDS write error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Write variable-length .dat path if present
|
||||
if resp.DatPathLen > 0 {
|
||||
if _, err := conn.Write([]byte(resp.DatPath)); err != nil {
|
||||
glog.V(2).Infof("UDS write dat path error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +240,14 @@ func (u *UdsServer) handleLocate(req *LocateRequest) *LocateResponse {
|
||||
resp.Offset = uint64(nv.Offset.ToActualOffset())
|
||||
resp.Length = uint64(nv.Size)
|
||||
|
||||
glog.V(3).Infof("UDS: located %s -> vol=%d offset=%d size=%d", fid, volumeId, resp.Offset, resp.Length)
|
||||
// Include .dat file path so sidecar knows the exact filename
|
||||
// (SeaweedFS uses {collection}_{id}.dat when collection is non-empty)
|
||||
datPath := v.DataFileName() + ".dat"
|
||||
if len(datPath) <= UdsMaxDatPathLen {
|
||||
resp.DatPath = datPath
|
||||
resp.DatPathLen = uint16(len(datPath))
|
||||
}
|
||||
|
||||
glog.V(3).Infof("UDS: located %s -> vol=%d offset=%d size=%d dat=%s", fid, volumeId, resp.Offset, resp.Length, datPath)
|
||||
return resp
|
||||
}
|
||||
|
||||
@@ -167,6 +167,12 @@ func TestUdsServerProtocol(t *testing.T) {
|
||||
if status != UdsStatusError {
|
||||
t.Errorf("Expected UdsStatusError (%d) for nil VolumeServer, got %d", UdsStatusError, status)
|
||||
}
|
||||
|
||||
// DatPathLen should be 0 for error responses
|
||||
datPathLen := binary.LittleEndian.Uint16(respBuf[24:26])
|
||||
if datPathLen != 0 {
|
||||
t.Errorf("Expected DatPathLen=0 for error, got %d", datPathLen)
|
||||
}
|
||||
}
|
||||
|
||||
// TestUdsSocketCleanup tests that existing socket is removed
|
||||
|
||||
Reference in New Issue
Block a user