remove safeMode behavior in startup (#10645)

In almost all scenarios MinIO now is
mostly ready for all sub-systems
independently, safe-mode is not useful
anymore and do not serve its original
intended purpose.

allow server to be fully functional
even with config partially configured,
this is to cater for availability of actual
I/O v/s manually fixing the server.

In k8s like environments it will never make
sense to take pod into safe-mode state,
because there is no real access to perform
any remote operation on them.
This commit is contained in:
Harshavardhana 2020-10-09 09:59:52 -07:00 committed by GitHub
parent 1738eb24b1
commit a0d0645128
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 139 additions and 268 deletions

View File

@ -42,7 +42,7 @@ import (
func validateAdminReqConfigKV(ctx context.Context, w http.ResponseWriter, r *http.Request) (auth.Credentials, ObjectLayer) { func validateAdminReqConfigKV(ctx context.Context, w http.ResponseWriter, r *http.Request) (auth.Credentials, ObjectLayer) {
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil { if objectAPI == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return auth.Credentials{}, nil return auth.Credentials{}, nil

View File

@ -35,7 +35,7 @@ func validateAdminUsersReq(ctx context.Context, w http.ResponseWriter, r *http.R
var adminAPIErr APIErrorCode var adminAPIErr APIErrorCode
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return nil, cred return nil, cred
@ -386,7 +386,7 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque
defer logger.AuditLog(w, r, "AddServiceAccount", mustGetClaimsFromToken(r)) defer logger.AuditLog(w, r, "AddServiceAccount", mustGetClaimsFromToken(r))
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return
@ -465,7 +465,7 @@ func (a adminAPIHandlers) ListServiceAccounts(w http.ResponseWriter, r *http.Req
defer logger.AuditLog(w, r, "ListServiceAccounts", mustGetClaimsFromToken(r)) defer logger.AuditLog(w, r, "ListServiceAccounts", mustGetClaimsFromToken(r))
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return
@ -520,7 +520,7 @@ func (a adminAPIHandlers) DeleteServiceAccount(w http.ResponseWriter, r *http.Re
defer logger.AuditLog(w, r, "DeleteServiceAccount", mustGetClaimsFromToken(r)) defer logger.AuditLog(w, r, "DeleteServiceAccount", mustGetClaimsFromToken(r))
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return
@ -579,7 +579,7 @@ func (a adminAPIHandlers) AccountUsageInfoHandler(w http.ResponseWriter, r *http
defer logger.AuditLog(w, r, "AccountUsageInfo", mustGetClaimsFromToken(r)) defer logger.AuditLog(w, r, "AccountUsageInfo", mustGetClaimsFromToken(r))
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return

View File

@ -899,7 +899,7 @@ func validateAdminReq(ctx context.Context, w http.ResponseWriter, r *http.Reques
var cred auth.Credentials var cred auth.Credentials
var adminAPIErr APIErrorCode var adminAPIErr APIErrorCode
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil { if objectAPI == nil || globalNotificationSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return nil, cred return nil, cred
@ -1490,11 +1490,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque
} }
} }
mode := "safemode" mode := "online"
if newObjectLayerFn() != nil {
mode = "online"
}
server := getLocalServerProperty(globalEndpoints, r) server := getLocalServerProperty(globalEndpoints, r)
servers := globalNotificationSys.ServerInfo() servers := globalNotificationSys.ServerInfo()
servers = append(servers, server) servers = append(servers, server)

View File

@ -808,7 +808,7 @@ func (h *healSequence) traverseAndHeal() {
func (h *healSequence) healMinioSysMeta(metaPrefix string) func() error { func (h *healSequence) healMinioSysMeta(metaPrefix string) func() error {
return func() error { return func() error {
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil { if objectAPI == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -844,7 +844,7 @@ func (h *healSequence) healDiskFormat() error {
} }
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil { if objectAPI == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -864,7 +864,7 @@ func (h *healSequence) healBuckets(bucketsOnly bool) error {
} }
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil { if objectAPI == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -886,7 +886,7 @@ func (h *healSequence) healBuckets(bucketsOnly bool) error {
// healBucket - traverses and heals given bucket // healBucket - traverses and heals given bucket
func (h *healSequence) healBucket(bucket string, bucketsOnly bool) error { func (h *healSequence) healBucket(bucket string, bucketsOnly bool) error {
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil { if objectAPI == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -932,7 +932,7 @@ func (h *healSequence) healBucket(bucket string, bucketsOnly bool) error {
// healObject - heal the given object and record result // healObject - heal the given object and record result
func (h *healSequence) healObject(bucket, object, versionID string) error { func (h *healSequence) healObject(bucket, object, versionID string) error {
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil { if objectAPI == nil {
return errServerNotInitialized return errServerNotInitialized
} }

View File

@ -703,10 +703,6 @@ func generateMultiDeleteResponse(quiet bool, deletedObjects []DeletedObject, err
} }
func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) { func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) {
if newObjectLayerFn() == nil {
// Server still in safe mode.
w.Header().Set(xhttp.MinIOServerStatus, "safemode")
}
setCommonHeaders(w) setCommonHeaders(w)
if mType != mimeNone { if mType != mimeNone {
w.Header().Set(xhttp.ContentType, string(mType)) w.Header().Set(xhttp.ContentType, string(mType))
@ -773,10 +769,6 @@ func writeErrorResponse(ctx context.Context, w http.ResponseWriter, err APIError
// The request is from browser and also if browser // The request is from browser and also if browser
// is enabled we need to redirect. // is enabled we need to redirect.
if browser && globalBrowserEnabled { if browser && globalBrowserEnabled {
if newObjectLayerFn() == nil {
// server still in safe mode.
w.Header().Set(xhttp.MinIOServerStatus, "safemode")
}
w.Header().Set(xhttp.Location, minioReservedBucketPath+reqURL.Path) w.Header().Set(xhttp.Location, minioReservedBucketPath+reqURL.Path)
w.WriteHeader(http.StatusTemporaryRedirect) w.WriteHeader(http.StatusTemporaryRedirect)
return return

View File

@ -32,28 +32,15 @@ func newHTTPServerFn() *xhttp.Server {
return globalHTTPServer return globalHTTPServer
} }
func newObjectLayerWithoutSafeModeFn() ObjectLayer {
globalObjLayerMutex.Lock()
defer globalObjLayerMutex.Unlock()
return globalObjectAPI
}
func newObjectLayerFn() ObjectLayer { func newObjectLayerFn() ObjectLayer {
globalObjLayerMutex.Lock() globalObjLayerMutex.Lock()
defer globalObjLayerMutex.Unlock() defer globalObjLayerMutex.Unlock()
if globalSafeMode {
return nil
}
return globalObjectAPI return globalObjectAPI
} }
func newCachedObjectLayerFn() CacheObjectLayer { func newCachedObjectLayerFn() CacheObjectLayer {
globalObjLayerMutex.Lock() globalObjLayerMutex.Lock()
defer globalObjLayerMutex.Unlock() defer globalObjLayerMutex.Unlock()
if globalSafeMode {
return nil
}
return globalCacheObjectAPI return globalCacheObjectAPI
} }

View File

@ -34,7 +34,7 @@ func NewBucketSSEConfigSys() *BucketSSEConfigSys {
// Get - gets bucket encryption config for the given bucket. // Get - gets bucket encryption config for the given bucket.
func (sys *BucketSSEConfigSys) Get(bucket string) (*bucketsse.BucketSSEConfig, error) { func (sys *BucketSSEConfigSys) Get(bucket string) (*bucketsse.BucketSSEConfig, error) {
if globalIsGateway { if globalIsGateway {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }

View File

@ -31,7 +31,7 @@ type LifecycleSys struct{}
// Get - gets lifecycle config associated to a given bucket name. // Get - gets lifecycle config associated to a given bucket name.
func (sys *LifecycleSys) Get(bucketName string) (lc *lifecycle.Lifecycle, err error) { func (sys *LifecycleSys) Get(bucketName string) (lc *lifecycle.Lifecycle, err error) {
if globalIsGateway { if globalIsGateway {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }

View File

@ -72,7 +72,7 @@ func (sys *BucketMetadataSys) Set(bucket string, meta BucketMetadata) {
// Update update bucket metadata for the specified config file. // Update update bucket metadata for the specified config file.
// The configData data should not be modified after being sent here. // The configData data should not be modified after being sent here.
func (sys *BucketMetadataSys) Update(bucket string, configFile string, configData []byte) error { func (sys *BucketMetadataSys) Update(bucket string, configFile string, configData []byte) error {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -275,7 +275,7 @@ func (sys *BucketMetadataSys) GetLifecycleConfig(bucket string) (*lifecycle.Life
func (sys *BucketMetadataSys) GetNotificationConfig(bucket string) (*event.Config, error) { func (sys *BucketMetadataSys) GetNotificationConfig(bucket string) (*event.Config, error) {
if globalIsGateway && globalGatewayName == NASBackendGateway { if globalIsGateway && globalGatewayName == NASBackendGateway {
// Only needed in case of NAS gateway. // Only needed in case of NAS gateway.
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -313,7 +313,7 @@ func (sys *BucketMetadataSys) GetSSEConfig(bucket string) (*bucketsse.BucketSSEC
// The returned object may not be modified. // The returned object may not be modified.
func (sys *BucketMetadataSys) GetPolicyConfig(bucket string) (*policy.Policy, error) { func (sys *BucketMetadataSys) GetPolicyConfig(bucket string) (*policy.Policy, error) {
if globalIsGateway { if globalIsGateway {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -376,7 +376,7 @@ func (sys *BucketMetadataSys) GetBucketTargetsConfig(bucket string) (*madmin.Buc
// GetConfig returns a specific configuration from the bucket metadata. // GetConfig returns a specific configuration from the bucket metadata.
// The returned object may not be modified. // The returned object may not be modified.
func (sys *BucketMetadataSys) GetConfig(bucket string) (BucketMetadata, error) { func (sys *BucketMetadataSys) GetConfig(bucket string) (BucketMetadata, error) {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return newBucketMetadata(bucket), errServerNotInitialized return newBucketMetadata(bucket), errServerNotInitialized
} }

View File

@ -33,7 +33,7 @@ type BucketObjectLockSys struct{}
// Get - Get retention configuration. // Get - Get retention configuration.
func (sys *BucketObjectLockSys) Get(bucketName string) (r objectlock.Retention, err error) { func (sys *BucketObjectLockSys) Get(bucketName string) (r objectlock.Retention, err error) {
if globalIsGateway { if globalIsGateway {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return r, errServerNotInitialized return r, errServerNotInitialized
} }

View File

@ -63,7 +63,7 @@ func parseBucketQuota(bucket string, data []byte) (quotaCfg *madmin.BucketQuota,
} }
func (sys *BucketQuotaSys) check(ctx context.Context, bucket string, size int64) error { func (sys *BucketQuotaSys) check(ctx context.Context, bucket string, size int64) error {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return errServerNotInitialized return errServerNotInitialized
} }

View File

@ -38,7 +38,7 @@ import (
// gets replication config associated to a given bucket name. // gets replication config associated to a given bucket name.
func getReplicationConfig(ctx context.Context, bucketName string) (rc *replication.Config, err error) { func getReplicationConfig(ctx context.Context, bucketName string) (rc *replication.Config, err error) {
if globalIsGateway { if globalIsGateway {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }

View File

@ -462,7 +462,7 @@ func (f *folderScanner) scanQueuedLevels(ctx context.Context, folders []cachedFo
continue continue
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
continue continue
} }

View File

@ -300,7 +300,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
// Once endpoints are finalized, initialize the new object api in safe mode. // Once endpoints are finalized, initialize the new object api in safe mode.
globalObjLayerMutex.Lock() globalObjLayerMutex.Lock()
globalSafeMode = true
globalObjectAPI = newObject globalObjectAPI = newObject
globalObjLayerMutex.Unlock() globalObjLayerMutex.Unlock()
@ -325,7 +324,7 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
if enableIAMOps { if enableIAMOps {
// Initialize IAM sys. // Initialize IAM sys.
startBackgroundIAMLoad(GlobalContext) startBackgroundIAMLoad(GlobalContext, newObject)
} }
if globalCacheConfig.Enabled { if globalCacheConfig.Enabled {
@ -353,11 +352,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
// - compression // - compression
verifyObjectLayerFeatures("gateway "+gatewayName, newObject) verifyObjectLayerFeatures("gateway "+gatewayName, newObject)
// Disable safe mode operation, after all initialization is over.
globalObjLayerMutex.Lock()
globalSafeMode = false
globalObjLayerMutex.Unlock()
// Prints the formatted startup message once object layer is initialized. // Prints the formatted startup message once object layer is initialized.
if !globalCLIContext.Quiet { if !globalCLIContext.Quiet {
mode := globalMinioModeGatewayPrefix + gatewayName mode := globalMinioModeGatewayPrefix + gatewayName

View File

@ -268,11 +268,6 @@ var (
globalBackgroundHealRoutine *healRoutine globalBackgroundHealRoutine *healRoutine
globalBackgroundHealState *allHealState globalBackgroundHealState *allHealState
// Only enabled when one of the sub-systems fail
// to initialize, this allows for administrators to
// fix the system.
globalSafeMode bool
// If writes to FS backend should be O_SYNC. // If writes to FS backend should be O_SYNC.
globalFSOSync bool globalFSOSync bool

View File

@ -411,8 +411,8 @@ func (sys *IAMSys) doIAMConfigMigration(ctx context.Context) error {
// Loads IAM users and policies in background, any un-handled // Loads IAM users and policies in background, any un-handled
// error means this code can potentially crash the server // error means this code can potentially crash the server
// in such a situation manual intervention is necessary. // in such a situation manual intervention is necessary.
func startBackgroundIAMLoad(ctx context.Context) { func startBackgroundIAMLoad(ctx context.Context, objAPI ObjectLayer) {
go globalIAMSys.Init(ctx, newObjectLayerWithoutSafeModeFn()) go globalIAMSys.Init(ctx, objAPI)
} }
// Init - initializes config system by reading entries from config/iam // Init - initializes config system by reading entries from config/iam
@ -514,7 +514,7 @@ func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer) {
// DeletePolicy - deletes a canned policy from backend or etcd. // DeletePolicy - deletes a canned policy from backend or etcd.
func (sys *IAMSys) DeletePolicy(policyName string) error { func (sys *IAMSys) DeletePolicy(policyName string) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -567,7 +567,7 @@ func (sys *IAMSys) DeletePolicy(policyName string) error {
// InfoPolicy - expands the canned policy into its JSON structure. // InfoPolicy - expands the canned policy into its JSON structure.
func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) { func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return iampolicy.Policy{}, errServerNotInitialized return iampolicy.Policy{}, errServerNotInitialized
} }
@ -585,7 +585,7 @@ func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) {
// ListPolicies - lists all canned policies. // ListPolicies - lists all canned policies.
func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) { func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -607,7 +607,7 @@ func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) {
// SetPolicy - sets a new name policy. // SetPolicy - sets a new name policy.
func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error { func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -629,7 +629,7 @@ func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error {
// DeleteUser - delete user (only for long-term users not STS users). // DeleteUser - delete user (only for long-term users not STS users).
func (sys *IAMSys) DeleteUser(accessKey string) error { func (sys *IAMSys) DeleteUser(accessKey string) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -699,7 +699,7 @@ func (sys *IAMSys) currentPolicies(policyName string) string {
// SetTempUser - set temporary user credentials, these credentials have an expiry. // SetTempUser - set temporary user credentials, these credentials have an expiry.
func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyName string) error { func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyName string) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -749,7 +749,7 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa
// ListUsers - list all users. // ListUsers - list all users.
func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) { func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -786,7 +786,7 @@ func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) {
// IsTempUser - returns if given key is a temporary user. // IsTempUser - returns if given key is a temporary user.
func (sys *IAMSys) IsTempUser(name string) (bool, error) { func (sys *IAMSys) IsTempUser(name string) (bool, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return false, errServerNotInitialized return false, errServerNotInitialized
} }
@ -804,7 +804,7 @@ func (sys *IAMSys) IsTempUser(name string) (bool, error) {
// IsServiceAccount - returns if given key is a service account // IsServiceAccount - returns if given key is a service account
func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) { func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return false, "", errServerNotInitialized return false, "", errServerNotInitialized
} }
@ -826,7 +826,7 @@ func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) {
// GetUserInfo - get info on a user. // GetUserInfo - get info on a user.
func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) { func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return u, errServerNotInitialized return u, errServerNotInitialized
} }
@ -872,7 +872,7 @@ func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) {
// SetUserStatus - sets current user status, supports disabled or enabled. // SetUserStatus - sets current user status, supports disabled or enabled.
func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus) error { func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -918,7 +918,7 @@ func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus)
// NewServiceAccount - create a new service account // NewServiceAccount - create a new service account
func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, sessionPolicy *iampolicy.Policy) (auth.Credentials, error) { func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, sessionPolicy *iampolicy.Policy) (auth.Credentials, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return auth.Credentials{}, errServerNotInitialized return auth.Credentials{}, errServerNotInitialized
} }
@ -985,7 +985,7 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, ses
// ListServiceAccounts - lists all services accounts associated to a specific user // ListServiceAccounts - lists all services accounts associated to a specific user
func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([]string, error) { func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([]string, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -1010,7 +1010,7 @@ func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([
// GetServiceAccountParent - gets information about a service account // GetServiceAccountParent - gets information about a service account
func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string) (string, error) { func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string) (string, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return "", errServerNotInitialized return "", errServerNotInitialized
} }
@ -1027,7 +1027,7 @@ func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string
// DeleteServiceAccount - delete a service account // DeleteServiceAccount - delete a service account
func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) error { func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1056,7 +1056,7 @@ func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) e
// SetUser - set user credentials and policy. // SetUser - set user credentials and policy.
func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error { func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1094,7 +1094,7 @@ func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error {
// SetUserSecretKey - sets user secret key // SetUserSecretKey - sets user secret key
func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error { func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1123,7 +1123,7 @@ func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error {
// GetUser - get user credentials // GetUser - get user credentials
func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) { func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return cred, false return cred, false
} }
@ -1187,7 +1187,7 @@ func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) {
// AddUsersToGroup - adds users to a group, creating the group if // AddUsersToGroup - adds users to a group, creating the group if
// needed. No error if user(s) already are in the group. // needed. No error if user(s) already are in the group.
func (sys *IAMSys) AddUsersToGroup(group string, members []string) error { func (sys *IAMSys) AddUsersToGroup(group string, members []string) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1248,7 +1248,7 @@ func (sys *IAMSys) AddUsersToGroup(group string, members []string) error {
// RemoveUsersFromGroup - remove users from group. If no users are // RemoveUsersFromGroup - remove users from group. If no users are
// given, and the group is empty, deletes the group as well. // given, and the group is empty, deletes the group as well.
func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error { func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1329,7 +1329,7 @@ func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
// SetGroupStatus - enable/disabled a group // SetGroupStatus - enable/disabled a group
func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error { func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1365,7 +1365,7 @@ func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error {
// GetGroupDescription - builds up group description // GetGroupDescription - builds up group description
func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err error) { func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return gd, errServerNotInitialized return gd, errServerNotInitialized
} }
@ -1406,7 +1406,7 @@ func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err e
// ListGroups - lists groups. // ListGroups - lists groups.
func (sys *IAMSys) ListGroups() (r []string, err error) { func (sys *IAMSys) ListGroups() (r []string, err error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return r, errServerNotInitialized return r, errServerNotInitialized
} }
@ -1430,7 +1430,7 @@ func (sys *IAMSys) ListGroups() (r []string, err error) {
// PolicyDBSet - sets a policy for a user or group in the PolicyDB. // PolicyDBSet - sets a policy for a user or group in the PolicyDB.
func (sys *IAMSys) PolicyDBSet(name, policy string, isGroup bool) error { func (sys *IAMSys) PolicyDBSet(name, policy string, isGroup bool) error {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1497,7 +1497,7 @@ func (sys *IAMSys) policyDBSet(name, policyName string, userType IAMUserType, is
// be a member of multiple groups, this function returns an array of // be a member of multiple groups, this function returns an array of
// applicable policies (each group is mapped to at most one policy). // applicable policies (each group is mapped to at most one policy).
func (sys *IAMSys) PolicyDBGet(name string, isGroup bool) ([]string, error) { func (sys *IAMSys) PolicyDBGet(name string, isGroup bool) ([]string, error) {
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if objectAPI == nil || sys == nil || sys.store == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }

View File

@ -35,7 +35,7 @@ const (
lockMaintenanceInterval = 30 * time.Second lockMaintenanceInterval = 30 * time.Second
// Lock validity check interval. // Lock validity check interval.
lockValidityCheckInterval = 2 * time.Minute lockValidityCheckInterval = 30 * time.Second
) )
// To abstract a node over network. // To abstract a node over network.
@ -242,7 +242,7 @@ func getLongLivedLocks(interval time.Duration) map[Endpoint][]nameLockRequesterI
// //
// We will ignore the error, and we will retry later to get a resolve on this lock // We will ignore the error, and we will retry later to get a resolve on this lock
func lockMaintenance(ctx context.Context, interval time.Duration) error { func lockMaintenance(ctx context.Context, interval time.Duration) error {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return nil return nil
} }
@ -332,7 +332,7 @@ func startLockMaintenance(ctx context.Context) {
// no need to start the lock maintenance // no need to start the lock maintenance
// if ObjectAPI is not initialized. // if ObjectAPI is not initialized.
for { for {
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue

View File

@ -161,7 +161,7 @@ func gatewayMetricsPrometheus(ch chan<- prometheus.Metric) {
return return
} }
objLayer := newObjectLayerWithoutSafeModeFn() objLayer := newObjectLayerFn()
// Service not initialized yet // Service not initialized yet
if objLayer == nil { if objLayer == nil {
return return
@ -372,7 +372,7 @@ func networkMetricsPrometheus(ch chan<- prometheus.Metric) {
// Populates prometheus with bucket usage metrics, this metrics // Populates prometheus with bucket usage metrics, this metrics
// is only enabled if crawler is enabled. // is only enabled if crawler is enabled.
func bucketUsageMetricsPrometheus(ch chan<- prometheus.Metric) { func bucketUsageMetricsPrometheus(ch chan<- prometheus.Metric) {
objLayer := newObjectLayerWithoutSafeModeFn() objLayer := newObjectLayerFn()
// Service not initialized yet // Service not initialized yet
if objLayer == nil { if objLayer == nil {
return return
@ -435,7 +435,7 @@ func bucketUsageMetricsPrometheus(ch chan<- prometheus.Metric) {
// collects storage metrics for MinIO server in Prometheus specific format // collects storage metrics for MinIO server in Prometheus specific format
// and sends to given channel // and sends to given channel
func storageMetricsPrometheus(ch chan<- prometheus.Metric) { func storageMetricsPrometheus(ch chan<- prometheus.Metric) {
objLayer := newObjectLayerWithoutSafeModeFn() objLayer := newObjectLayerFn()
// Service not initialized yet // Service not initialized yet
if objLayer == nil { if objLayer == nil {
return return

View File

@ -613,18 +613,12 @@ func (sys *NotificationSys) Init(ctx context.Context, buckets []BucketInfo, objA
return errServerNotInitialized return errServerNotInitialized
} }
// In gateway mode, notifications are not supported. // In gateway mode, notifications are not supported - except NAS gateway.
if globalIsGateway && !objAPI.IsNotificationSupported() { if globalIsGateway && !objAPI.IsNotificationSupported() {
return nil return nil
} }
if globalConfigTargetList != nil { logger.LogIf(ctx, sys.targetList.Add(globalConfigTargetList.Targets()...))
for _, target := range globalConfigTargetList.Targets() {
if err := sys.targetList.Add(target); err != nil {
return err
}
}
}
go func() { go func() {
for res := range sys.targetResCh { for res := range sys.targetResCh {

View File

@ -64,7 +64,7 @@ func (s *peerRESTServer) DeletePolicyHandler(w http.ResponseWriter, r *http.Requ
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -97,7 +97,7 @@ func (s *peerRESTServer) LoadPolicyHandler(w http.ResponseWriter, r *http.Reques
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -130,7 +130,7 @@ func (s *peerRESTServer) LoadPolicyMappingHandler(w http.ResponseWriter, r *http
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -164,7 +164,7 @@ func (s *peerRESTServer) DeleteServiceAccountHandler(w http.ResponseWriter, r *h
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -197,7 +197,7 @@ func (s *peerRESTServer) LoadServiceAccountHandler(w http.ResponseWriter, r *htt
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -230,7 +230,7 @@ func (s *peerRESTServer) DeleteUserHandler(w http.ResponseWriter, r *http.Reques
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -263,7 +263,7 @@ func (s *peerRESTServer) LoadUserHandler(w http.ResponseWriter, r *http.Request)
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -307,7 +307,7 @@ func (s *peerRESTServer) LoadGroupHandler(w http.ResponseWriter, r *http.Request
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -609,7 +609,7 @@ func (s *peerRESTServer) LoadBucketMetadataHandler(w http.ResponseWriter, r *htt
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -657,7 +657,7 @@ func (s *peerRESTServer) ReloadFormatHandler(w http.ResponseWriter, r *http.Requ
return return
} }
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
s.writeErrorResponse(w, errServerNotInitialized) s.writeErrorResponse(w, errServerNotInitialized)
return return
@ -767,7 +767,7 @@ func (s *peerRESTServer) GetLocalDiskIDs(w http.ResponseWriter, r *http.Request)
ctx := newContext(r, w, "GetLocalDiskIDs") ctx := newContext(r, w, "GetLocalDiskIDs")
objLayer := newObjectLayerWithoutSafeModeFn() objLayer := newObjectLayerFn()
// Service not initialized yet // Service not initialized yet
if objLayer == nil { if objLayer == nil {

View File

@ -186,7 +186,7 @@ func newAllSubsystems() {
globalBucketTargetSys = NewBucketTargetSys() globalBucketTargetSys = NewBucketTargetSys()
} }
func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) { func initServer(ctx context.Context, newObject ObjectLayer) (err error) {
// Create cancel context to control 'newRetryTimer' go routine. // Create cancel context to control 'newRetryTimer' go routine.
retryCtx, cancel := context.WithCancel(ctx) retryCtx, cancel := context.WithCancel(ctx)
@ -199,33 +199,33 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
// appropriately. This is also true for rotation of encrypted // appropriately. This is also true for rotation of encrypted
// content. // content.
txnLk := newObject.NewNSLock(retryCtx, minioMetaBucket, minioConfigPrefix+"/transaction.lock") txnLk := newObject.NewNSLock(retryCtx, minioMetaBucket, minioConfigPrefix+"/transaction.lock")
var locked bool defer func() {
defer func(txnLk RWLocker) {
if locked {
txnLk.Unlock()
}
if err != nil { if err != nil {
var cerr config.Err var cerr config.Err
// For any config error, we don't need to drop into safe-mode // For any config error, we don't need to drop into safe-mode
// instead its a user error and should be fixed by user. // instead its a user error and should be fixed by user.
if errors.As(err, &cerr) { if errors.As(err, &cerr) {
logger.FatalIf(err, "Unable to initialize the server")
return return
} }
// If context was canceled // If context was canceled
if errors.Is(err, context.Canceled) { if errors.Is(err, context.Canceled) {
logger.FatalIf(err, "Server startup canceled upon user request")
return return
} }
}
// Prints the formatted startup message in safe mode operation. // Prints the formatted startup message, if err is not nil then it prints additional information as well.
// Drops-into safe mode where users need to now manually recover printStartupMessage(getAPIEndpoints(), err)
// the server.
printStartupSafeModeMessage(getAPIEndpoints(), err) if globalActiveCred.Equal(auth.DefaultCredentials) {
msg := fmt.Sprintf("Detected default credentials '%s', please change the credentials immediately using 'MINIO_ACCESS_KEY' and 'MINIO_SECRET_KEY'", globalActiveCred)
logger.StartupMessage(color.RedBold(msg))
}
<-globalOSSignalCh <-globalOSSignalCh
} }()
}(txnLk)
// Enable background operations for erasure coding // Enable background operations for erasure coding
if globalIsErasure { if globalIsErasure {
@ -256,9 +256,6 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
continue continue
} }
// locked successful
locked = true
// These messages only meant primarily for distributed setup, so only log during distributed setup. // These messages only meant primarily for distributed setup, so only log during distributed setup.
if globalIsDistErasure { if globalIsDistErasure {
logger.Info("Waiting for all MinIO sub-systems to be initialized.. lock acquired") logger.Info("Waiting for all MinIO sub-systems to be initialized.. lock acquired")
@ -270,7 +267,8 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
if err = handleEncryptedConfigBackend(newObject); err == nil { if err = handleEncryptedConfigBackend(newObject); err == nil {
// Upon success migrating the config, initialize all sub-systems // Upon success migrating the config, initialize all sub-systems
// if all sub-systems initialized successfully return right away // if all sub-systems initialized successfully return right away
if err = initAllSubsystems(retryCtx, newObject); err == nil { if err = initAllSubsystems(ctx, newObject); err == nil {
txnLk.Unlock()
// All successful return. // All successful return.
if globalIsDistErasure { if globalIsDistErasure {
// These messages only meant primarily for distributed setup, so only log during distributed setup. // These messages only meant primarily for distributed setup, so only log during distributed setup.
@ -280,6 +278,8 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
} }
} }
txnLk.Unlock() // Unlock the transaction lock and allow other nodes to acquire the lock if possible.
// One of these retriable errors shall be retried. // One of these retriable errors shall be retried.
if errors.Is(err, errDiskNotFound) || if errors.Is(err, errDiskNotFound) ||
errors.Is(err, errConfigNotFound) || errors.Is(err, errConfigNotFound) ||
@ -288,8 +288,6 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
errors.As(err, &wquorum) || errors.As(err, &wquorum) ||
isErrBucketNotFound(err) { isErrBucketNotFound(err) {
logger.Info("Waiting for all MinIO sub-systems to be initialized.. possible cause (%v)", err) 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.
locked = false
continue continue
} }
@ -299,7 +297,7 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
// Return an error when retry is canceled or deadlined // Return an error when retry is canceled or deadlined
if err = retryCtx.Err(); err != nil { if err = retryCtx.Err(); err != nil {
return fmt.Errorf("Unable to initialize sub-systems: %w", err) return err
} }
// Retry was canceled successfully. // Retry was canceled successfully.
@ -314,13 +312,13 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
// ensures top level retry works accordingly. // ensures top level retry works accordingly.
// List buckets to heal, and be re-used for loading configs. // List buckets to heal, and be re-used for loading configs.
var buckets []BucketInfo var buckets []BucketInfo
rquorum := InsufficientReadQuorum{}
wquorum := InsufficientWriteQuorum{}
if globalIsErasure { if globalIsErasure {
buckets, err = newObject.ListBucketsHeal(ctx) buckets, err = newObject.ListBucketsHeal(ctx)
if err != nil { if err != nil {
return fmt.Errorf("Unable to list buckets to heal: %w", err) return fmt.Errorf("Unable to list buckets to heal: %w", err)
} }
rquorum := InsufficientReadQuorum{}
wquorum := InsufficientWriteQuorum{}
for _, bucket := range buckets { for _, bucket := range buckets {
if err = newObject.MakeBucketWithLocation(ctx, bucket.Name, BucketOptions{}); err != nil { if err = newObject.MakeBucketWithLocation(ctx, bucket.Name, BucketOptions{}); err != nil {
if errors.As(err, &wquorum) || errors.As(err, &rquorum) { if errors.As(err, &wquorum) || errors.As(err, &rquorum) {
@ -344,8 +342,17 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
// Initialize config system. // Initialize config system.
if err = globalConfigSys.Init(newObject); err != nil { if err = globalConfigSys.Init(newObject); err != nil {
if errors.Is(err, errDiskNotFound) ||
errors.Is(err, errConfigNotFound) ||
errors.Is(err, context.DeadlineExceeded) ||
errors.As(err, &rquorum) ||
errors.As(err, &wquorum) ||
isErrBucketNotFound(err) {
return fmt.Errorf("Unable to initialize config system: %w", err) return fmt.Errorf("Unable to initialize config system: %w", err)
} }
// Any other config errors we simply print a message and proceed forward.
logger.LogIf(ctx, err)
}
// Populate existing buckets to the etcd backend // Populate existing buckets to the etcd backend
if globalDNSConfig != nil { if globalDNSConfig != nil {
@ -353,20 +360,25 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
go initFederatorBackend(buckets, newObject) go initFederatorBackend(buckets, newObject)
} }
// Initialize bucket metadata sub-system. if globalCacheConfig.Enabled {
if err = globalBucketMetadataSys.Init(ctx, buckets, newObject); err != nil { // initialize the new disk cache objects.
return fmt.Errorf("Unable to initialize bucket metadata sub-system: %w", err) var cacheAPI CacheObjectLayer
cacheAPI, err = newServerCacheObjects(ctx, globalCacheConfig)
logger.FatalIf(err, "Unable to initialize disk caching")
globalObjLayerMutex.Lock()
globalCacheObjectAPI = cacheAPI
globalObjLayerMutex.Unlock()
} }
// Initialize bucket metadata sub-system.
globalBucketMetadataSys.Init(ctx, buckets, newObject)
// Initialize notification system. // Initialize notification system.
if err = globalNotificationSys.Init(ctx, buckets, newObject); err != nil { globalNotificationSys.Init(ctx, buckets, newObject)
return fmt.Errorf("Unable to initialize notification system: %w", err)
}
// Initialize bucket targets sub-system. // Initialize bucket targets sub-system.
if err = globalBucketTargetSys.Init(ctx, buckets, newObject); err != nil { globalBucketTargetSys.Init(ctx, buckets, newObject)
return fmt.Errorf("Unable to initialize bucket target sub-system: %w", err)
}
return nil return nil
} }
@ -488,42 +500,15 @@ func serverMain(ctx *cli.Context) {
// Once endpoints are finalized, initialize the new object api in safe mode. // Once endpoints are finalized, initialize the new object api in safe mode.
globalObjLayerMutex.Lock() globalObjLayerMutex.Lock()
globalSafeMode = true
globalObjectAPI = newObject globalObjectAPI = newObject
globalObjLayerMutex.Unlock() globalObjLayerMutex.Unlock()
go initDataCrawler(GlobalContext, newObject) go initDataCrawler(GlobalContext, newObject)
logger.FatalIf(initSafeMode(GlobalContext, newObject), "Unable to initialize server switching into safe-mode")
// Initialize users credentials and policies in background. // Initialize users credentials and policies in background.
go startBackgroundIAMLoad(GlobalContext) go startBackgroundIAMLoad(GlobalContext, newObject)
if globalCacheConfig.Enabled { initServer(GlobalContext, newObject)
// initialize the new disk cache objects.
var cacheAPI CacheObjectLayer
cacheAPI, err = newServerCacheObjects(GlobalContext, globalCacheConfig)
logger.FatalIf(err, "Unable to initialize disk caching")
globalObjLayerMutex.Lock()
globalCacheObjectAPI = cacheAPI
globalObjLayerMutex.Unlock()
}
// Disable safe mode operation, after all initialization is over.
globalObjLayerMutex.Lock()
globalSafeMode = false
globalObjLayerMutex.Unlock()
// Prints the formatted startup message once object layer is initialized.
printStartupMessage(getAPIEndpoints())
if globalActiveCred.Equal(auth.DefaultCredentials) {
msg := fmt.Sprintf("Detected default credentials '%s', please change the credentials immediately using 'MINIO_ACCESS_KEY' and 'MINIO_SECRET_KEY'", globalActiveCred)
logger.StartupMessage(color.RedBold(msg))
}
<-globalOSSignalCh
} }
// Initialize object layer with the supplied disks, objectLayer is nil upon any error. // Initialize object layer with the supplied disks, objectLayer is nil upon any error.

View File

@ -33,7 +33,6 @@ import (
// Documentation links, these are part of message printing code. // Documentation links, these are part of message printing code.
const ( const (
mcQuickStartGuide = "https://docs.min.io/docs/minio-client-quickstart-guide" mcQuickStartGuide = "https://docs.min.io/docs/minio-client-quickstart-guide"
mcAdminQuickStartGuide = "https://docs.min.io/docs/minio-admin-complete-guide.html"
goQuickStartGuide = "https://docs.min.io/docs/golang-client-quickstart-guide" goQuickStartGuide = "https://docs.min.io/docs/golang-client-quickstart-guide"
jsQuickStartGuide = "https://docs.min.io/docs/javascript-client-quickstart-guide" jsQuickStartGuide = "https://docs.min.io/docs/javascript-client-quickstart-guide"
javaQuickStartGuide = "https://docs.min.io/docs/java-client-quickstart-guide" javaQuickStartGuide = "https://docs.min.io/docs/java-client-quickstart-guide"
@ -52,65 +51,13 @@ func mustGetStorageInfo(objAPI ObjectLayer) StorageInfo {
return storageInfo return storageInfo
} }
func printStartupSafeModeMessage(apiEndpoints []string, err error) {
logStartupMessage(color.RedBold("Server startup failed with '%v'", err))
logStartupMessage(color.RedBold("Server switching to safe mode"))
logStartupMessage(color.RedBold("Please use 'mc admin config' commands fix this issue"))
// Object layer is initialized then print StorageInfo in safe mode.
objAPI := newObjectLayerWithoutSafeModeFn()
if objAPI != nil {
if msg := getStorageInfoMsgSafeMode(mustGetStorageInfo(objAPI)); msg != "" {
logStartupMessage(msg)
}
}
// Get saved credentials.
cred := globalActiveCred
// Get saved region.
region := globalServerRegion
strippedAPIEndpoints := stripStandardPorts(apiEndpoints)
apiEndpointStr := strings.Join(strippedAPIEndpoints, " ")
// Colorize the message and print.
logStartupMessage(color.Red("Endpoint: ") + color.Bold(fmt.Sprintf(getFormatStr(len(apiEndpointStr), 1), apiEndpointStr)))
if color.IsTerminal() && !globalCLIContext.Anonymous {
logStartupMessage(color.Red("AccessKey: ") + color.Bold(fmt.Sprintf("%s ", cred.AccessKey)))
logStartupMessage(color.Red("SecretKey: ") + color.Bold(fmt.Sprintf("%s ", cred.SecretKey)))
if region != "" {
logStartupMessage(color.Red("Region: ") + color.Bold(fmt.Sprintf(getFormatStr(len(region), 3), region)))
}
}
// Prints `mc` cli configuration message chooses
// first endpoint as default.
alias := "myminio"
endPoint := strippedAPIEndpoints[0]
// Configure 'mc', following block prints platform specific information for minio client admin commands.
if color.IsTerminal() && !globalCLIContext.Anonymous {
logStartupMessage(color.RedBold("\nCommand-line Access: ") + mcAdminQuickStartGuide)
if runtime.GOOS == globalWindowsOSName {
mcMessage := fmt.Sprintf("> mc.exe alias set %s %s %s %s --api s3v4", alias,
endPoint, cred.AccessKey, cred.SecretKey)
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
mcMessage = "> mc.exe admin config --help"
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
} else {
mcMessage := fmt.Sprintf("$ mc alias set %s %s %s %s --api s3v4", alias,
endPoint, cred.AccessKey, cred.SecretKey)
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
mcMessage = "$ mc admin config --help"
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
}
}
}
// Prints the formatted startup message. // Prints the formatted startup message.
func printStartupMessage(apiEndpoints []string) { func printStartupMessage(apiEndpoints []string, err error) {
if err != nil {
logStartupMessage(color.RedBold("Server startup failed with '%v'", err))
logStartupMessage(color.RedBold("Not all features may be available on this server"))
logStartupMessage(color.RedBold("Please use 'mc admin' commands to further investigate this issue"))
}
strippedAPIEndpoints := stripStandardPorts(apiEndpoints) strippedAPIEndpoints := stripStandardPorts(apiEndpoints)
// If cache layer is enabled, print cache capacity. // If cache layer is enabled, print cache capacity.
@ -254,23 +201,6 @@ func printObjectAPIMsg() {
logStartupMessage(color.Blue(" .NET: ") + fmt.Sprintf(getFormatStr(len(dotnetQuickStartGuide), 6), dotnetQuickStartGuide)) logStartupMessage(color.Blue(" .NET: ") + fmt.Sprintf(getFormatStr(len(dotnetQuickStartGuide), 6), dotnetQuickStartGuide))
} }
// Get formatted disk/storage info message.
func getStorageInfoMsgSafeMode(storageInfo StorageInfo) string {
var msg string
var mcMessage string
if storageInfo.Backend.Type == BackendErasure {
if storageInfo.Backend.OfflineDisks.Sum() > 0 {
mcMessage = "Use `mc admin info` to look for latest server/disk info\n"
}
diskInfo := fmt.Sprintf(" %d Online, %d Offline. ", storageInfo.Backend.OnlineDisks.Sum(), storageInfo.Backend.OfflineDisks.Sum())
msg += color.Red("Status:") + fmt.Sprintf(getFormatStr(len(diskInfo), 8), diskInfo)
}
if len(mcMessage) > 0 {
msg = fmt.Sprintf("%s %s", mcMessage, msg)
}
return msg
}
// Get formatted disk/storage info message. // Get formatted disk/storage info message.
func getStorageInfoMsg(storageInfo StorageInfo) string { func getStorageInfoMsg(storageInfo StorageInfo) string {
var msg string var msg string

View File

@ -102,5 +102,5 @@ func TestPrintStartupMessage(t *testing.T) {
} }
apiEndpoints := []string{"http://127.0.0.1:9000"} apiEndpoints := []string{"http://127.0.0.1:9000"}
printStartupMessage(apiEndpoints) printStartupMessage(apiEndpoints, nil)
} }

View File

@ -60,7 +60,7 @@ func handleSignals() {
} }
} }
if objAPI := newObjectLayerWithoutSafeModeFn(); objAPI != nil { if objAPI := newObjectLayerFn(); objAPI != nil {
oerr = objAPI.Shutdown(context.Background()) oerr = objAPI.Shutdown(context.Background())
logger.LogIf(context.Background(), oerr) logger.LogIf(context.Background(), oerr)
} }

View File

@ -2077,16 +2077,10 @@ func registerAPIFunctions(muxRouter *mux.Router, objLayer ObjectLayer, apiFuncti
// operation // operation
api := objectAPIHandlers{ api := objectAPIHandlers{
ObjectAPI: func() ObjectLayer { ObjectAPI: func() ObjectLayer {
if !globalSafeMode {
return globalObjectAPI return globalObjectAPI
}
return nil
}, },
CacheAPI: func() CacheObjectLayer { CacheAPI: func() CacheObjectLayer {
if !globalSafeMode {
return globalCacheObjectAPI return globalCacheObjectAPI
}
return nil
}, },
} }

View File

@ -366,7 +366,7 @@ func (s *xlStorage) CrawlAndGetDataUsage(ctx context.Context, cache dataUsageCac
} }
// Get object api // Get object api
objAPI := newObjectLayerWithoutSafeModeFn() objAPI := newObjectLayerFn()
if objAPI == nil { if objAPI == nil {
return cache, errServerNotInitialized return cache, errServerNotInitialized
} }

View File

@ -86,6 +86,10 @@ func (list *TargetList) Remove(targetIDSet TargetIDSet) {
// Targets - list all targets // Targets - list all targets
func (list *TargetList) Targets() []Target { func (list *TargetList) Targets() []Target {
if list == nil {
return []Target{}
}
list.RLock() list.RLock()
defer list.RUnlock() defer list.RUnlock()