xl: Quit early when EC config is incorrect (#16390)

Co-authored-by: Anis Elleuch <anis@min.io>
This commit is contained in:
Anis Elleuch 2023-01-10 08:07:45 +01:00 committed by GitHub
parent 52b88b52f0
commit 2146ed4033
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 20 deletions

View file

@ -94,11 +94,14 @@ func newErasureServerPools(ctx context.Context, endpointServerPools EndpointServ
// -- Default for Standard Storage class is, parity = 3 - disks 6, 7
// -- Default for Standard Storage class is, parity = 4 - disks 8 to 16
if commonParityDrives == 0 {
commonParityDrives = ecDrivesNoConfig(ep.DrivesPerSet)
commonParityDrives, err = ecDrivesNoConfig(ep.DrivesPerSet)
if err != nil {
return nil, err
}
}
if err = storageclass.ValidateParity(commonParityDrives, ep.DrivesPerSet); err != nil {
return nil, fmt.Errorf("parity validation returned an error %w <- (%d, %d), for pool(%s)", err, commonParityDrives, ep.DrivesPerSet, humanize.Ordinal(i+1))
return nil, fmt.Errorf("parity validation returned an error: %w <- (%d, %d), for pool(%s)", err, commonParityDrives, ep.DrivesPerSet, humanize.Ordinal(i+1))
}
storageDisks[i], formats[i], err = waitForFormatErasure(local, ep.Endpoints, i+1,

View file

@ -354,10 +354,6 @@ func newErasureSets(ctx context.Context, endpoints PoolEndpoints, storageDisks [
endpointStrings[i] = endpoint.String()
}
if defaultParityCount == 0 {
logger.Error("Warning: Default parity set to 0. This can lead to data loss.")
}
// Initialize the erasure sets instance.
s := &erasureSets{
sets: make([]*erasureObjects, setCount),

View file

@ -191,7 +191,12 @@ func TestNewErasureSets(t *testing.T) {
}
ep := PoolEndpoints{Endpoints: endpoints}
if _, err := newErasureSets(ctx, ep, storageDisks, format, ecDrivesNoConfig(16), 0); err != nil {
parity, err := ecDrivesNoConfig(16)
if err != nil {
t.Fatalf("Unexpected error during EC drive config: %v", err)
}
if _, err := newErasureSets(ctx, ep, storageDisks, format, parity, 0); err != nil {
t.Fatalf("Unable to initialize erasure")
}
}

View file

@ -741,7 +741,10 @@ func fixFormatErasureV3(storageDisks []StorageAPI, endpoints Endpoints, formats
func initFormatErasure(ctx context.Context, storageDisks []StorageAPI, setCount, setDriveCount int, deploymentID, distributionAlgo string, sErrs []error) (*formatErasureV3, error) {
format := newFormatErasureV3(setCount, setDriveCount)
formats := make([]*formatErasureV3, len(storageDisks))
wantAtMost := ecDrivesNoConfig(setDriveCount)
wantAtMost, err := ecDrivesNoConfig(setDriveCount)
if err != nil {
return nil, err
}
for i := 0; i < setCount; i++ {
hostCount := make(map[string]int, setDriveCount)
@ -795,13 +798,12 @@ func initFormatErasure(ctx context.Context, storageDisks []StorageAPI, setCount,
// ecDrivesNoConfig returns the erasure coded drives in a set if no config has been set.
// It will attempt to read it from env variable and fall back to drives/2.
func ecDrivesNoConfig(setDriveCount int) int {
sc, _ := storageclass.LookupConfig(config.KVS{}, setDriveCount)
ecDrives := sc.GetParityForSC(storageclass.STANDARD)
if ecDrives < 0 {
ecDrives = storageclass.DefaultParityBlocks(setDriveCount)
func ecDrivesNoConfig(setDriveCount int) (int, error) {
sc, err := storageclass.LookupConfig(config.KVS{}, setDriveCount)
if err != nil {
return 0, err
}
return ecDrives
return sc.GetParityForSC(storageclass.STANDARD), nil
}
// Make Erasure backend meta volumes.

View file

@ -722,6 +722,11 @@ func serverMain(ctx *cli.Context) {
// Prints the formatted startup message, if err is not nil then it prints additional information as well.
printStartupMessage(getAPIEndpoints(), err)
// Print a warning at the end of the startup banner so it is more noticeable
if globalStorageClass.GetParityForSC("") == 0 {
logger.Error("Warning: The standard parity is set to 0. This can lead to data loss.")
}
}()
region := globalSite.Region

View file

@ -304,12 +304,7 @@ func LookupConfig(kvs config.KVS, setDriveCount int) (cfg Config, err error) {
// Validation is done after parsing both the storage classes. This is needed because we need one
// storage class value to deduce the correct value of the other storage class.
if err = validateParity(cfg.Standard.Parity, cfg.RRS.Parity, setDriveCount); err != nil {
cfg.RRS.Parity = defaultRRSParity
if setDriveCount == 1 {
cfg.RRS.Parity = 0
}
cfg.Standard.Parity = DefaultParityBlocks(setDriveCount)
return cfg, err
return Config{}, err
}
return cfg, nil