diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 42474e723..fb9d42840 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -575,6 +575,16 @@ func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Reques return } + // Take a read lock on minio/config.json. NB minio is a + // reserved bucket name and wouldn't conflict with normal + // object operations. + configLock := globalNSMutex.NewNSLock(minioReservedBucket, minioConfigFile) + if configLock.GetRLock(globalObjectTimeout) != nil { + writeErrorResponseJSON(w, ErrOperationTimedOut, r.URL) + return + } + defer configLock.RUnlock() + // Get config.json - in distributed mode, the configuration // occurring on a quorum of the servers is returned. configBytes, err := getPeerConfig(globalAdminPeers) @@ -784,6 +794,15 @@ func (a adminAPIHandlers) UpdateCredentialsHandler(w http.ResponseWriter, return } + // Take a lock on minio/config.json. Prevents concurrent + // config file/credentials updates. + configLock := globalNSMutex.NewNSLock(minioReservedBucket, minioConfigFile) + if configLock.GetLock(globalObjectTimeout) != nil { + writeErrorResponseJSON(w, ErrOperationTimedOut, r.URL) + return + } + defer configLock.Unlock() + // Notify all other Minio peers to update credentials updateErrs := updateCredsOnPeers(creds) for peer, err := range updateErrs { diff --git a/cmd/admin-heal-ops.go b/cmd/admin-heal-ops.go index 5d7dca68b..76ad2e1ce 100644 --- a/cmd/admin-heal-ops.go +++ b/cmd/admin-heal-ops.go @@ -528,6 +528,13 @@ func (h *healSequence) healDiskFormat() error { return errServerNotInitialized } + // Acquire lock on format.json + formatLock := globalNSMutex.NewNSLock(minioMetaBucket, formatConfigFile) + if err := formatLock.GetLock(globalHealingTimeout); err != nil { + return errFnHealFromAPIErr(err) + } + defer formatLock.Unlock() + // Create a new set of storage instances to heal format.json. bootstrapDisks, err := initStorageDisks(globalEndpoints) if err != nil {