From a9db24cd052ae4b17773a6bb77b703536bb80039 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sun, 13 Dec 2020 19:44:57 -0800 Subject: [PATCH] master allocate volumes if ssd type runs out --- weed/server/master_grpc_server_volume.go | 2 +- weed/server/master_server_handlers.go | 2 +- weed/server/master_server_handlers_admin.go | 2 +- weed/topology/node.go | 11 +++++++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/weed/server/master_grpc_server_volume.go b/weed/server/master_grpc_server_volume.go index 0b41bce86..debb21b94 100644 --- a/weed/server/master_grpc_server_volume.go +++ b/weed/server/master_grpc_server_volume.go @@ -79,7 +79,7 @@ func (ms *MasterServer) Assign(ctx context.Context, req *master_pb.AssignRequest } if !ms.Topo.HasWritableVolume(option) { - if ms.Topo.FreeSpace() <= 0 { + if ms.Topo.AvailableSpaceFor(option) <= 0 { return nil, fmt.Errorf("No free volumes left!") } ms.vgLock.Lock() diff --git a/weed/server/master_server_handlers.go b/weed/server/master_server_handlers.go index ebcb7efd2..dc3df2348 100644 --- a/weed/server/master_server_handlers.go +++ b/weed/server/master_server_handlers.go @@ -112,7 +112,7 @@ func (ms *MasterServer) dirAssignHandler(w http.ResponseWriter, r *http.Request) } if !ms.Topo.HasWritableVolume(option) { - if ms.Topo.FreeSpace() <= 0 { + if ms.Topo.AvailableSpaceFor(option) <= 0 { writeJsonQuiet(w, r, http.StatusNotFound, operation.AssignResult{Error: "No free volumes left!"}) return } diff --git a/weed/server/master_server_handlers_admin.go b/weed/server/master_server_handlers_admin.go index ad4e4422d..1f340cb11 100644 --- a/weed/server/master_server_handlers_admin.go +++ b/weed/server/master_server_handlers_admin.go @@ -76,7 +76,7 @@ func (ms *MasterServer) volumeGrowHandler(w http.ResponseWriter, r *http.Request } if count, err = strconv.Atoi(r.FormValue("count")); err == nil { - if ms.Topo.FreeSpace() < int64(count*option.ReplicaPlacement.GetCopyCount()) { + if ms.Topo.AvailableSpaceFor(option) < int64(count*option.ReplicaPlacement.GetCopyCount()) { err = fmt.Errorf("only %d volumes left, not enough for %d", ms.Topo.FreeSpace(), count*option.ReplicaPlacement.GetCopyCount()) } else { count, err = ms.vg.GrowByCountAndType(ms.grpcDialOption, count, option, ms.Topo) diff --git a/weed/topology/node.go b/weed/topology/node.go index c916857c0..8f525021f 100644 --- a/weed/topology/node.go +++ b/weed/topology/node.go @@ -2,6 +2,7 @@ package topology import ( "errors" + "github.com/chrislusf/seaweedfs/weed/storage" "math/rand" "strings" "sync" @@ -148,6 +149,16 @@ func (n *NodeImpl) String() string { func (n *NodeImpl) Id() NodeId { return n.id } +func (n *NodeImpl) AvailableSpaceFor(option *VolumeGrowOption) int64 { + freeVolumeSlotCount := n.maxVolumeCount + n.remoteVolumeCount - n.volumeCount + if option.DiskType == storage.SsdType { + freeVolumeSlotCount = n.maxSsdVolumeCount - n.ssdVolumeCount + } + if n.ecShardCount > 0 { + freeVolumeSlotCount = freeVolumeSlotCount - n.ecShardCount/erasure_coding.DataShardsCount - 1 + } + return freeVolumeSlotCount +} func (n *NodeImpl) FreeSpace() int64 { freeVolumeSlotCount := n.maxVolumeCount + n.maxSsdVolumeCount + n.remoteVolumeCount - n.volumeCount - n.ssdVolumeCount if n.ecShardCount > 0 {