diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index fcd9af656..0b094c4eb 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -1277,7 +1277,7 @@ func deleteObjectPerfBucket(objectAPI ObjectLayer) { func validateObjPerfOptions(ctx context.Context, objectAPI ObjectLayer, concurrent int, size int, autotune bool) (sufficientCapacity bool, canAutotune bool, capacityErrMsg string) { storageInfo, _ := objectAPI.StorageInfo(ctx) capacityNeeded := uint64(concurrent * size) - capacity := uint64(GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo)) + capacity := GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo) if capacity < capacityNeeded { return false, false, fmt.Sprintf("not enough usable space available to perform speedtest - expected %s, got %s", diff --git a/cmd/erasure-server-pool.go b/cmd/erasure-server-pool.go index cedfe3add..e9972260c 100644 --- a/cmd/erasure-server-pool.go +++ b/cmd/erasure-server-pool.go @@ -238,6 +238,7 @@ func (z *erasureServerPools) GetRawData(ctx context.Context, volume, file string return nil } +// Return the count of disks in each pool func (z *erasureServerPools) SetDriveCounts() []int { setDriveCounts := make([]int, len(z.serverPools)) for i := range z.serverPools { diff --git a/cmd/erasure-single-drive.go b/cmd/erasure-single-drive.go index 08ea40a8a..f030f0aad 100644 --- a/cmd/erasure-single-drive.go +++ b/cmd/erasure-single-drive.go @@ -184,6 +184,10 @@ func (es *erasureSingle) Shutdown(ctx context.Context) error { return nil } +func (es *erasureSingle) SetDriveCounts() []int { + return []int{1} +} + func (es *erasureSingle) BackendInfo() (b madmin.BackendInfo) { b.Type = madmin.Erasure diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index 7c1a3768f..c3c5b556a 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -209,7 +209,13 @@ func (fs *FSObjects) Shutdown(ctx context.Context) error { // BackendInfo - returns backend information func (fs *FSObjects) BackendInfo() madmin.BackendInfo { - return madmin.BackendInfo{Type: madmin.FS} + return madmin.BackendInfo{ + Type: madmin.FS, + StandardSCData: []int{1}, + StandardSCParity: 0, + RRSCData: []int{1}, + RRSCParity: 0, + } } // LocalStorageInfo - returns underlying storage statistics. @@ -234,7 +240,7 @@ func (fs *FSObjects) StorageInfo(ctx context.Context) (StorageInfo, []error) { }, }, } - storageInfo.Backend.Type = madmin.FS + storageInfo.Backend = fs.BackendInfo() return storageInfo, nil } diff --git a/cmd/metrics-v2.go b/cmd/metrics-v2.go index f7449d3b1..13eee4896 100644 --- a/cmd/metrics-v2.go +++ b/cmd/metrics-v2.go @@ -1903,12 +1903,12 @@ func getClusterStorageMetrics() *MetricsGroup { metrics = append(metrics, Metric{ Description: getClusterCapacityUsageBytesMD(), - Value: GetTotalUsableCapacity(storageInfo.Disks, storageInfo), + Value: float64(GetTotalUsableCapacity(storageInfo.Disks, storageInfo)), }) metrics = append(metrics, Metric{ Description: getClusterCapacityUsageFreeBytesMD(), - Value: GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo), + Value: float64(GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo)), }) metrics = append(metrics, Metric{ diff --git a/cmd/metrics.go b/cmd/metrics.go index 6e663ea9b..3ea1e01c8 100644 --- a/cmd/metrics.go +++ b/cmd/metrics.go @@ -577,7 +577,7 @@ func storageMetricsPrometheus(ch chan<- prometheus.Metric) { "Total usable capacity online in the cluster", nil, nil), prometheus.GaugeValue, - GetTotalUsableCapacity(server.Disks, s), + float64(GetTotalUsableCapacity(server.Disks, s)), ) // Report total usable capacity free ch <- prometheus.MustNewConstMetric( @@ -586,7 +586,7 @@ func storageMetricsPrometheus(ch chan<- prometheus.Metric) { "Total free usable capacity online in the cluster", nil, nil), prometheus.GaugeValue, - GetTotalUsableCapacityFree(server.Disks, s), + float64(GetTotalUsableCapacityFree(server.Disks, s)), ) // MinIO Offline Disks per node diff --git a/cmd/notification-summary.go b/cmd/notification-summary.go index 8327da76e..57328ee4d 100644 --- a/cmd/notification-summary.go +++ b/cmd/notification-summary.go @@ -30,17 +30,17 @@ func GetTotalCapacity(diskInfo []madmin.Disk) (capacity uint64) { } // GetTotalUsableCapacity gets the total usable capacity in the cluster. -// This value is not an accurate representation of total usable in a multi-tenant deployment. -func GetTotalUsableCapacity(diskInfo []madmin.Disk, s StorageInfo) (capacity float64) { - raw := GetTotalCapacity(diskInfo) - var approxDataBlocks float64 - var actualDisks float64 - for _, scData := range s.Backend.StandardSCData { - approxDataBlocks += float64(scData) - actualDisks += float64(scData + s.Backend.StandardSCParity) +func GetTotalUsableCapacity(diskInfo []madmin.Disk, s StorageInfo) (capacity uint64) { + if globalIsGateway { + return 0 } - ratio := approxDataBlocks / actualDisks - return float64(raw) * ratio + for _, disk := range diskInfo { + // Ignore parity disks + if disk.DiskIndex < s.Backend.StandardSCData[disk.PoolIndex] { + capacity += disk.TotalSpace + } + } + return } // GetTotalCapacityFree gets the total capacity free in the cluster. @@ -52,15 +52,16 @@ func GetTotalCapacityFree(diskInfo []madmin.Disk) (capacity uint64) { } // GetTotalUsableCapacityFree gets the total usable capacity free in the cluster. -// This value is not an accurate representation of total free in a multi-tenant deployment. -func GetTotalUsableCapacityFree(diskInfo []madmin.Disk, s StorageInfo) (capacity float64) { - raw := GetTotalCapacityFree(diskInfo) - var approxDataBlocks float64 - var actualDisks float64 - for _, scData := range s.Backend.StandardSCData { - approxDataBlocks += float64(scData) - actualDisks += float64(scData + s.Backend.StandardSCParity) +func GetTotalUsableCapacityFree(diskInfo []madmin.Disk, s StorageInfo) (capacity uint64) { + if globalIsGateway { + return 0 } - ratio := approxDataBlocks / actualDisks - return float64(raw) * ratio + + for _, disk := range diskInfo { + // Ignore parity disks + if disk.DiskIndex < s.Backend.StandardSCData[disk.PoolIndex] { + capacity += disk.AvailableSpace + } + } + return }