mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-16 20:26:45 +00:00
fix(ec): don't fabricate a stub .vif when mounting an EC volume (#9951)
When an EC volume's .vif was missing, NewEcVolume wrote a stub holding only the version. That stub implies the default 10+4 ratio with DatFileSize=0 and no encode identity, which the custom-ratio resolver and the startup credibility checks then read as an authoritative config -- masking the real ratio of a custom-ratio volume and defeating the byte-exact .vif gate. Mount with in-memory defaults instead and leave the real .vif to the encoder or a recovery tool. The Rust volume server already behaves this way.
This commit is contained in:
@@ -173,8 +173,13 @@ func NewEcVolume(diskType types.DiskType, dir string, dirIdx string, collection
|
||||
ev.ECContext = NewDefaultECContext(collection, vid)
|
||||
}
|
||||
} else {
|
||||
glog.Warningf("vif file not found,volumeId:%d, filename:%s", vid, vifFileName)
|
||||
volume_info.SaveVolumeInfo(dataBaseFileName+".vif", &volume_server_pb.VolumeInfo{Version: uint32(ev.Version)})
|
||||
// Don't fabricate a stub .vif here: a version-only stub implies the
|
||||
// default 10+4 ratio with DatFileSize=0 and no encode identity, which
|
||||
// the custom-ratio resolver and the startup credibility checks must not
|
||||
// mistake for an authoritative config. Mount with in-memory defaults and
|
||||
// leave the real .vif to the encoder or a recovery tool (the Rust volume
|
||||
// server already behaves this way).
|
||||
glog.Warningf("vif file not found, using defaults, volumeId:%d, filename:%s", vid, vifFileName)
|
||||
ev.ECContext = NewDefaultECContext(collection, vid)
|
||||
}
|
||||
|
||||
|
||||
@@ -91,3 +91,31 @@ func TestNewEcVolumeLoadsEncodeTsNs(t *testing.T) {
|
||||
t.Errorf("EncodeTsNs = %d, want %d", ev.EncodeTsNs, tsNs)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewEcVolumeDoesNotWriteStubVif pins that mounting an EC volume whose .vif
|
||||
// is missing does NOT fabricate a stub .vif. A version-only stub would imply
|
||||
// the default ratio with DatFileSize=0 and no encode identity, which the
|
||||
// custom-ratio resolver and startup credibility checks must not trust.
|
||||
func TestNewEcVolumeDoesNotWriteStubVif(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
const vid = needle.VolumeId(124)
|
||||
base := EcShardFileName("", dir, int(vid))
|
||||
|
||||
if err := os.WriteFile(base+".ecx", nil, 0o644); err != nil {
|
||||
t.Fatalf("write .ecx: %v", err)
|
||||
}
|
||||
|
||||
ev, err := NewEcVolume(types.HardDriveType, dir, dir, "", vid)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEcVolume: %v", err)
|
||||
}
|
||||
defer ev.Close()
|
||||
|
||||
if _, statErr := os.Stat(base + ".vif"); !os.IsNotExist(statErr) {
|
||||
t.Fatalf("mounting without a .vif must not create one, stat err=%v", statErr)
|
||||
}
|
||||
// Mount still succeeds with the build's default EC ratio in memory.
|
||||
if ev.ECContext == nil || ev.ECContext.DataShards != int(DataShardsCount) {
|
||||
t.Fatalf("expected default EC context, got %+v", ev.ECContext)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user