mirror of
https://github.com/minio/minio.git
synced 2025-11-20 18:06:10 -05:00
fix: unexpected logging with bucket metadata conversions (#9519)
This commit is contained in:
@@ -160,53 +160,45 @@ func newAllSubsystems() {
|
||||
globalBucketQuotaSys = NewBucketQuotaSys()
|
||||
}
|
||||
|
||||
func initSafeMode(buckets []BucketInfo) (err error) {
|
||||
func initSafeMode() (err error) {
|
||||
newObject := newObjectLayerWithoutSafeModeFn()
|
||||
|
||||
// Construct path to config/transaction.lock for locking
|
||||
transactionConfigPrefix := minioConfigPrefix + "/transaction.lock"
|
||||
|
||||
// Make sure to hold lock for entire migration to avoid
|
||||
// such that only one server should migrate the entire config
|
||||
// at a given time, this big transaction lock ensures this
|
||||
// appropriately. This is also true for rotation of encrypted
|
||||
// content.
|
||||
objLock := newObject.NewNSLock(GlobalContext, minioMetaBucket, transactionConfigPrefix)
|
||||
if err = objLock.GetLock(globalOperationTimeout); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func(objLock RWLocker) {
|
||||
objLock.Unlock()
|
||||
txnLk := newObject.NewNSLock(GlobalContext, minioMetaBucket, minioConfigPrefix+"/transaction.lock")
|
||||
defer func(txnLk RWLocker) {
|
||||
txnLk.Unlock()
|
||||
|
||||
if err != nil {
|
||||
var cerr config.Err
|
||||
// For any config error, we don't need to drop into safe-mode
|
||||
// instead its a user error and should be fixed by user.
|
||||
if errors.As(err, &cerr) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prints the formatted startup message in safe mode operation.
|
||||
// Drops-into safe mode where users need to now manually recover
|
||||
// the server.
|
||||
printStartupSafeModeMessage(getAPIEndpoints(), err)
|
||||
|
||||
// Initialization returned error reaching safe mode and
|
||||
// not proceeding waiting for admin action.
|
||||
handleSignals()
|
||||
}
|
||||
}(objLock)
|
||||
|
||||
// Migrate all backend configs to encrypted backend configs, optionally
|
||||
// handles rotating keys for encryption.
|
||||
if err = handleEncryptedConfigBackend(newObject, true); err != nil {
|
||||
return fmt.Errorf("Unable to handle encrypted backend for config, iam and policies: %w", err)
|
||||
}
|
||||
}(txnLk)
|
||||
|
||||
// **** WARNING ****
|
||||
// Migrating to encrypted backend should happen before initialization of any
|
||||
// sub-systems, make sure that we do not move the above codeblock elsewhere.
|
||||
// Create cancel context to control 'newRetryTimer' go routine.
|
||||
retryCtx, cancel := context.WithCancel(GlobalContext)
|
||||
|
||||
// Validate and initialize all subsystems.
|
||||
doneCh := make(chan struct{})
|
||||
defer close(doneCh)
|
||||
// Indicate to our routine to exit cleanly upon return.
|
||||
defer cancel()
|
||||
|
||||
// Initializing sub-systems needs a retry mechanism for
|
||||
// the following reasons:
|
||||
@@ -214,43 +206,67 @@ func initSafeMode(buckets []BucketInfo) (err error) {
|
||||
// of the object layer.
|
||||
// - Write quorum not met when upgrading configuration
|
||||
// version is needed, migration is needed etc.
|
||||
retryTimerCh := newRetryTimerSimple(doneCh)
|
||||
for {
|
||||
rquorum := InsufficientReadQuorum{}
|
||||
wquorum := InsufficientWriteQuorum{}
|
||||
bucketNotFound := BucketNotFound{}
|
||||
var err error
|
||||
select {
|
||||
case n := <-retryTimerCh:
|
||||
if err = initAllSubsystems(buckets, newObject); err != nil {
|
||||
if errors.Is(err, errDiskNotFound) ||
|
||||
errors.As(err, &rquorum) ||
|
||||
errors.As(err, &wquorum) ||
|
||||
errors.As(err, &bucketNotFound) {
|
||||
if n < 5 {
|
||||
logger.Info("Waiting for all sub-systems to be initialized..")
|
||||
} else {
|
||||
logger.Info("Waiting for all sub-systems to be initialized.. %v", err)
|
||||
}
|
||||
continue
|
||||
rquorum := InsufficientReadQuorum{}
|
||||
wquorum := InsufficientWriteQuorum{}
|
||||
optimeout := OperationTimedOut{}
|
||||
for n := 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 {
|
||||
// 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.
|
||||
if err = handleEncryptedConfigBackend(newObject, true); err == nil {
|
||||
// Upon success migrating the config, initialize all sub-systems
|
||||
// if all sub-systems initialized successfully return right away
|
||||
if err = initAllSubsystems(newObject); err == nil {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case <-globalOSSignalCh:
|
||||
if err == nil {
|
||||
return errors.New("Initializing sub-systems stopped gracefully")
|
||||
}
|
||||
return fmt.Errorf("Unable to initialize sub-systems: %w", err)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Any other unhandled return right here.
|
||||
return fmt.Errorf("Unable to initialize sub-systems: %w", err)
|
||||
}
|
||||
|
||||
// Return an error when retry is canceled or deadlined
|
||||
if err = retryCtx.Err(); err != nil {
|
||||
return fmt.Errorf("Unable to initialize sub-systems: %w", err)
|
||||
}
|
||||
|
||||
// Retry was canceled successfully.
|
||||
return errors.New("Initializing sub-systems stopped gracefully")
|
||||
}
|
||||
|
||||
func initAllSubsystems(buckets []BucketInfo, newObject ObjectLayer) (err error) {
|
||||
func initAllSubsystems(newObject ObjectLayer) (err error) {
|
||||
// List buckets to be re-used for loading configs.
|
||||
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 {
|
||||
return fmt.Errorf("Unable to initialize config system: %w", err)
|
||||
}
|
||||
|
||||
if globalEtcdClient != nil {
|
||||
// **** WARNING ****
|
||||
// Migrating to encrypted backend on etcd should happen before initialization of
|
||||
@@ -294,6 +310,11 @@ func initAllSubsystems(buckets []BucketInfo, newObject ObjectLayer) (err error)
|
||||
return fmt.Errorf("Unable to initialize bucket quota system: %w", err)
|
||||
}
|
||||
|
||||
// Populate existing buckets to the etcd backend
|
||||
if globalDNSConfig != nil {
|
||||
initFederatorBackend(buckets, newObject)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -458,13 +479,7 @@ func serverMain(ctx *cli.Context) {
|
||||
|
||||
go startBackgroundOps(GlobalContext, newObject)
|
||||
|
||||
// Calls New() and initializes all sub-systems.
|
||||
buckets, err := newObject.ListBuckets(GlobalContext)
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to list buckets")
|
||||
}
|
||||
|
||||
logger.FatalIf(initSafeMode(buckets), "Unable to initialize server switching into safe-mode")
|
||||
logger.FatalIf(initSafeMode(), "Unable to initialize server switching into safe-mode")
|
||||
|
||||
if globalCacheConfig.Enabled {
|
||||
// initialize the new disk cache objects.
|
||||
@@ -477,11 +492,6 @@ func serverMain(ctx *cli.Context) {
|
||||
globalObjLayerMutex.Unlock()
|
||||
}
|
||||
|
||||
// Populate existing buckets to the etcd backend
|
||||
if globalDNSConfig != nil {
|
||||
initFederatorBackend(buckets, newObject)
|
||||
}
|
||||
|
||||
// Disable safe mode operation, after all initialization is over.
|
||||
globalObjLayerMutex.Lock()
|
||||
globalSafeMode = false
|
||||
|
||||
Reference in New Issue
Block a user