diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 6a50f3ab1..3327eda5a 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -984,6 +984,31 @@ func (a adminAPIHandlers) ObjectSpeedtestHandler(w http.ResponseWriter, r *http. duration = time.Second * 10 } + // ignores any errors here. + storageInfo, _ := objectAPI.StorageInfo(ctx) + capacityNeeded := uint64(concurrent * size) + capacity := uint64(GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo)) + + if capacity < capacityNeeded { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, AdminError{ + Code: "XMinioSpeedtestInsufficientCapacity", + Message: fmt.Sprintf("not enough usable space available to perform speedtest - expected %s, got %s", + humanize.IBytes(capacityNeeded), humanize.IBytes(capacity)), + StatusCode: http.StatusInsufficientStorage, + }), r.URL) + return + } + + // Verify if we can employ autotune without running out of capacity, + // if we do run out of capacity, make sure to turn-off autotuning + // in such situations. + newConcurrent := concurrent + (concurrent+1)/2 + autoTunedCapacityNeeded := uint64(newConcurrent * size) + if autotune && capacity < autoTunedCapacityNeeded { + // Turn-off auto-tuning if next possible concurrency would reach beyond disk capacity. + autotune = false + } + deleteBucket := func() { objectAPI.DeleteBucket(context.Background(), pathJoin(minioMetaBucket, "speedtest"), DeleteBucketOptions{ Force: true,