mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
Support supplying custom drives per set count (#6261)
This commit is contained in:
parent
7c14cdb60e
commit
f26325c988
@ -18,6 +18,8 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/minio/minio-go/pkg/set"
|
"github.com/minio/minio-go/pkg/set"
|
||||||
@ -69,10 +71,26 @@ func getSetIndexes(args []string, totalSizes []uint64) (setIndexes [][]uint64, e
|
|||||||
return nil, errInvalidArgument
|
return nil, errInvalidArgument
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isValidSetSize - checks whether given count is a valid set size for erasure coding.
|
||||||
|
isValidSetSize := func(count uint64) bool {
|
||||||
|
return (count >= setSizes[0] && count <= setSizes[len(setSizes)-1] && count%2 == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var customSetDriveCount uint64
|
||||||
|
if v := os.Getenv("MINIO_ERASURE_SET_DRIVE_COUNT"); v != "" {
|
||||||
|
customSetDriveCount, err = strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, uiErrInvalidErasureSetSize(err)
|
||||||
|
}
|
||||||
|
if !isValidSetSize(customSetDriveCount) {
|
||||||
|
return nil, uiErrInvalidErasureSetSize(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setIndexes = make([][]uint64, len(totalSizes))
|
setIndexes = make([][]uint64, len(totalSizes))
|
||||||
for _, totalSize := range totalSizes {
|
for _, totalSize := range totalSizes {
|
||||||
// Check if totalSize has minimum range upto setSize
|
// Check if totalSize has minimum range upto setSize
|
||||||
if totalSize < setSizes[0] {
|
if totalSize < setSizes[0] || totalSize < customSetDriveCount {
|
||||||
return nil, uiErrInvalidNumberOfErasureEndpoints(nil)
|
return nil, uiErrInvalidNumberOfErasureEndpoints(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,9 +113,24 @@ func getSetIndexes(args []string, totalSizes []uint64) (setIndexes [][]uint64, e
|
|||||||
setSize = commonSize
|
setSize = commonSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// isValidSetSize - checks whether given count is a valid set size for erasure coding.
|
possibleSetCounts := func(setSize uint64) (ss []uint64) {
|
||||||
isValidSetSize := func(count uint64) bool {
|
for _, s := range setSizes {
|
||||||
return (count >= setSizes[0] && count <= setSizes[len(setSizes)-1] && count%2 == 0)
|
if setSize%s == 0 {
|
||||||
|
ss = append(ss, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss
|
||||||
|
}
|
||||||
|
|
||||||
|
if customSetDriveCount > 0 {
|
||||||
|
msg := fmt.Sprintf("Invalid set drive count, leads to non-uniform distribution for the given number of disks. Possible values for custom set count are %d", possibleSetCounts(setSize))
|
||||||
|
if customSetDriveCount > setSize {
|
||||||
|
return nil, uiErrInvalidErasureSetSize(nil).Msg(msg)
|
||||||
|
}
|
||||||
|
if setSize%customSetDriveCount != 0 {
|
||||||
|
return nil, uiErrInvalidErasureSetSize(nil).Msg(msg)
|
||||||
|
}
|
||||||
|
setSize = customSetDriveCount
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether setSize is with the supported range.
|
// Check whether setSize is with the supported range.
|
||||||
|
@ -18,6 +18,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -84,6 +85,65 @@ func TestGetDivisibleSize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test tests calculating set indexes with ENV override for drive count.
|
||||||
|
func TestGetSetIndexesEnvOverride(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
args []string
|
||||||
|
totalSizes []uint64
|
||||||
|
indexes [][]uint64
|
||||||
|
envOverride string
|
||||||
|
success bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
[]string{"data{1...64}"},
|
||||||
|
[]uint64{64},
|
||||||
|
[][]uint64{{8, 8, 8, 8, 8, 8, 8, 8}},
|
||||||
|
"8",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"data{1...60}"},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
"8",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"data{1...64}"},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
"-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"data{1...64}"},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
"2",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
|
||||||
|
if err := os.Setenv("MINIO_ERASURE_SET_DRIVE_COUNT", testCase.envOverride); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
gotIndexes, err := getSetIndexes(testCase.args, testCase.totalSizes)
|
||||||
|
if err != nil && testCase.success {
|
||||||
|
t.Errorf("Expected success but failed instead %s", err)
|
||||||
|
}
|
||||||
|
if err == nil && !testCase.success {
|
||||||
|
t.Errorf("Expected failure but passed instead")
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(testCase.indexes, gotIndexes) {
|
||||||
|
t.Errorf("Expected %v, got %v", testCase.indexes, gotIndexes)
|
||||||
|
}
|
||||||
|
os.Unsetenv("MINIO_ERASURE_SET_DRIVE_COUNT")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test tests calculating set indexes.
|
// Test tests calculating set indexes.
|
||||||
func TestGetSetIndexes(t *testing.T) {
|
func TestGetSetIndexes(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -29,6 +29,12 @@ var (
|
|||||||
"Browser can only accept `on` and `off` values. To disable web browser access, set this value to `off`",
|
"Browser can only accept `on` and `off` values. To disable web browser access, set this value to `off`",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
uiErrInvalidErasureSetSize = newUIErrFn(
|
||||||
|
"Invalid erasure set size",
|
||||||
|
"Please check the passed value",
|
||||||
|
"Erasure set can only accept any of [4, 6, 8, 10, 12, 14, 16] values.",
|
||||||
|
)
|
||||||
|
|
||||||
uiErrInvalidWormValue = newUIErrFn(
|
uiErrInvalidWormValue = newUIErrFn(
|
||||||
"Invalid WORM value",
|
"Invalid WORM value",
|
||||||
"Please check the passed value",
|
"Please check the passed value",
|
||||||
|
Loading…
Reference in New Issue
Block a user