|
|
|
@ -208,11 +208,15 @@ func initSafeMode() (err error) { |
|
|
|
|
// version is needed, migration is needed etc.
|
|
|
|
|
rquorum := InsufficientReadQuorum{} |
|
|
|
|
wquorum := InsufficientWriteQuorum{} |
|
|
|
|
optimeout := OperationTimedOut{} |
|
|
|
|
for n := range newRetryTimerSimple(retryCtx) { |
|
|
|
|
for range newRetryTimerSimple(retryCtx) { |
|
|
|
|
// let one of the server acquire the lock, if not let them timeout.
|
|
|
|
|
// which shall be retried again by this loop.
|
|
|
|
|
if err = txnLk.GetLock(leaderLockTimeout); err == nil { |
|
|
|
|
if err = txnLk.GetLock(leaderLockTimeout); err != nil { |
|
|
|
|
logger.Info("Waiting for all MinIO sub-systems to be initialized.. trying to acquire lock") |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
logger.Info("Waiting for all MinIO sub-systems to be initialized.. lock acquired") |
|
|
|
|
|
|
|
|
|
// Migrate all backend configs to encrypted backend configs, optionally
|
|
|
|
|
// handles rotating keys for encryption, if there is any retriable failure
|
|
|
|
|
// that shall be retried if there is an error.
|
|
|
|
@ -220,25 +224,21 @@ func initSafeMode() (err error) { |
|
|
|
|
// Upon success migrating the config, initialize all sub-systems
|
|
|
|
|
// if all sub-systems initialized successfully return right away
|
|
|
|
|
if err = initAllSubsystems(newObject); err == nil { |
|
|
|
|
// All successful return.
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// One of these retriable errors shall be retried.
|
|
|
|
|
if errors.Is(err, errDiskNotFound) || |
|
|
|
|
errors.Is(err, errConfigNotFound) || |
|
|
|
|
errors.Is(err, context.Canceled) || |
|
|
|
|
errors.Is(err, context.DeadlineExceeded) || |
|
|
|
|
errors.As(err, &optimeout) || |
|
|
|
|
errors.As(err, &rquorum) || |
|
|
|
|
errors.As(err, &wquorum) || |
|
|
|
|
isErrBucketNotFound(err) { |
|
|
|
|
if n < 5 { |
|
|
|
|
logger.Info("Waiting for all MinIO sub-systems to be initialized..") |
|
|
|
|
} else { |
|
|
|
|
logger.Info("Waiting for all MinIO sub-systems to be initialized.. possible cause (%v)", err) |
|
|
|
|
} |
|
|
|
|
txnLk.Unlock() // Unlock the transaction lock and allow other nodes to acquire the lock if possible.
|
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -256,11 +256,42 @@ func initSafeMode() (err error) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func initAllSubsystems(newObject ObjectLayer) (err error) { |
|
|
|
|
// List buckets to be re-used for loading configs.
|
|
|
|
|
buckets, err := newObject.ListBuckets(GlobalContext) |
|
|
|
|
// %w is used by all error returns here to make sure
|
|
|
|
|
// we wrap the underlying error, make sure when you
|
|
|
|
|
// are modifying this code that you do so, if and when
|
|
|
|
|
// you want to add extra context to your error. This
|
|
|
|
|
// ensures top level retry works accordingly.
|
|
|
|
|
var buckets []BucketInfo |
|
|
|
|
if globalIsDistXL || globalIsXL { |
|
|
|
|
// List buckets to heal, and be re-used for loading configs.
|
|
|
|
|
buckets, err = newObject.ListBucketsHeal(GlobalContext) |
|
|
|
|
if err != nil { |
|
|
|
|
return fmt.Errorf("Unable to list buckets to heal: %w", err) |
|
|
|
|
} |
|
|
|
|
// Attempt a heal if possible and re-use the bucket names
|
|
|
|
|
// to reload their config.
|
|
|
|
|
wquorum := &InsufficientWriteQuorum{} |
|
|
|
|
rquorum := &InsufficientReadQuorum{} |
|
|
|
|
for _, bucket := range buckets { |
|
|
|
|
if err = newObject.MakeBucketWithLocation(GlobalContext, bucket.Name, ""); err != nil { |
|
|
|
|
if errors.As(err, &wquorum) || errors.As(err, &rquorum) { |
|
|
|
|
// Retrun the error upwards for the caller to retry.
|
|
|
|
|
return fmt.Errorf("Unable to heal bucket: %w", err) |
|
|
|
|
} |
|
|
|
|
if _, ok := err.(BucketExists); !ok { |
|
|
|
|
// ignore any other error and log for investigation.
|
|
|
|
|
logger.LogIf(GlobalContext, err) |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
// Bucket already exists, nothing that needs to be done.
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
buckets, err = newObject.ListBuckets(GlobalContext) |
|
|
|
|
if err != nil { |
|
|
|
|
return fmt.Errorf("Unable to list buckets: %w", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Initialize config system.
|
|
|
|
|
if err = globalConfigSys.Init(newObject); err != nil { |
|
|
|
|