diff --git a/weed/storage/store.go b/weed/storage/store.go index 7c41f1c35..064e7086f 100644 --- a/weed/storage/store.go +++ b/weed/storage/store.go @@ -292,7 +292,18 @@ func (s *Store) CollectHeartbeat() *master_pb.Heartbeat { collectionVolumeReadOnlyCount := make(map[string]map[string]uint8) for _, location := range s.Locations { var deleteVids []needle.VolumeId - maxVolumeCounts[string(location.DiskType)] += uint32(location.MaxVolumeCount) + effectiveMaxCount := location.MaxVolumeCount + if location.isDiskSpaceLow { + usedSlots := int32(location.LocalVolumesLen()) + if ecShardCount := location.EcShardCount(); ecShardCount > 0 { + usedSlots += int32((ecShardCount + erasure_coding.DataShardsCount - 1) / erasure_coding.DataShardsCount) + } + effectiveMaxCount = usedSlots + } + if effectiveMaxCount < 0 { + effectiveMaxCount = 0 + } + maxVolumeCounts[string(location.DiskType)] += uint32(effectiveMaxCount) location.volumesLock.RLock() for _, v := range location.volumes { curMaxFileKey, volumeMessage := v.ToVolumeInformationMessage() diff --git a/weed/storage/store_disk_space_test.go b/weed/storage/store_disk_space_test.go index 284657e3c..eaec8f628 100644 --- a/weed/storage/store_disk_space_test.go +++ b/weed/storage/store_disk_space_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/seaweedfs/seaweedfs/weed/storage/needle" + "github.com/seaweedfs/seaweedfs/weed/storage/types" ) func TestHasFreeDiskLocation(t *testing.T) { @@ -92,3 +93,31 @@ func TestHasFreeDiskLocation(t *testing.T) { }) } } + +func TestCollectHeartbeatRespectsLowDiskSpace(t *testing.T) { + diskType := types.ToDiskType("hdd") + location := &DiskLocation{ + volumes: make(map[needle.VolumeId]*Volume), + isDiskSpaceLow: true, + MaxVolumeCount: 10, + DiskType: diskType, + } + location.volumes[needle.VolumeId(1)] = &Volume{} + location.volumes[needle.VolumeId(2)] = &Volume{} + location.volumes[needle.VolumeId(3)] = &Volume{} + + store := &Store{ + Locations: []*DiskLocation{location}, + } + + hb := store.CollectHeartbeat() + if got := hb.MaxVolumeCounts[string(diskType)]; got != 3 { + t.Fatalf("expected low disk space to cap max volume count to used slots, got %d", got) + } + + location.isDiskSpaceLow = false + hb = store.CollectHeartbeat() + if got := hb.MaxVolumeCounts[string(diskType)]; got != 10 { + t.Fatalf("expected normal disk space to report configured max volume count, got %d", got) + } +}