mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-19 21:56:54 +00:00
topology: provisional volume update must not erase the reported disk id (#10687)
Volume growth registers a provisional record before it can know which directory the server chose, while the server's own report -- pushed during the AllocateVolume RPC -- carries the real disk id. The merge is last-writer-wins, so whichever lands second sticks, and fresh volumes nondeterministically show disk 0 on multi-dir servers. Keep the reported disk id when the provisional update carries none, before the report digest is computed so the stored record stays consistent with what the server keeps reporting. Claude-Session: https://claude.ai/code/session_01QdTEEPbg4MtcoEGwqbgtZC
This commit is contained in:
@@ -230,6 +230,14 @@ func (d *Disk) doAddOrUpdateVolume(v storage.VolumeInfo, fromReport bool) (isNew
|
||||
d.UpAdjustDiskUsageDelta(types.ToDiskType(v.DiskType), deltaDiskUsage)
|
||||
isNew = true
|
||||
} else {
|
||||
if !fromReport && v.DiskId == 0 && oldV.DiskId != 0 {
|
||||
// A provisional (grow-time) record carries no disk id -- the
|
||||
// master cannot know which directory the server chose. Keep the
|
||||
// one the server's report already named, before the digest below
|
||||
// is computed, or the stored record would drift from what the
|
||||
// server keeps reporting.
|
||||
v.DiskId = oldV.DiskId
|
||||
}
|
||||
if oldV.IsRemote() != v.IsRemote() {
|
||||
if v.IsRemote() {
|
||||
deltaDiskUsage.remoteVolumeCount = 1
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package topology
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/types"
|
||||
)
|
||||
|
||||
// A provisional (grow-time) registration carries no disk id; when it lands
|
||||
// after the server's own report -- the server pushes its report during the
|
||||
// AllocateVolume RPC, so either order happens -- it must not erase the disk id
|
||||
// the report recorded.
|
||||
func TestProvisionalUpdateKeepsReportedDiskId(t *testing.T) {
|
||||
disk := NewDisk(types.HardDriveType.String())
|
||||
|
||||
disk.AddOrUpdateVolume(storage.VolumeInfo{Id: 1, DiskId: 2})
|
||||
disk.AddProvisionalVolume(storage.VolumeInfo{Id: 1})
|
||||
|
||||
v, err := disk.GetVolumesById(1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v.DiskId != 2 {
|
||||
t.Fatalf("DiskId = %d, want 2 (provisional update clobbered the reported value)", v.DiskId)
|
||||
}
|
||||
|
||||
// A later server report naming a different disk still wins.
|
||||
disk.AddOrUpdateVolume(storage.VolumeInfo{Id: 1, DiskId: 1})
|
||||
if v, _ = disk.GetVolumesById(1); v.DiskId != 1 {
|
||||
t.Fatalf("DiskId = %d, want 1 (a real report must override)", v.DiskId)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user