Repository: minio/minio (language: go)

Issue:
listusers hang when  IAM sub-system initialization fails
## Expected Behavior
IAM sub-system initialization fails
![image](https://user-images.githubusercontent.com/92494511/161235109-a6f61907-fbfb-476d-860a-af4bade7017b.png)

Execute GET on /minio/admin/v3/list-users failed
## Current Behavior
Interface /minio/admin/v3/list-users hang

## Possible Solution


## Steps to Reproduce (for bugs)
Run Latest MinIO and create a single version first
```
exprot access_key=w7fs7xk6gikiRbbCJY
export secret_key=hvGcKlh+2IMNYbUa
minio server -C /home/minio/.minio --quiet  /export1
```
stop MinIO  and change access_key secret_key
```
exprot access_key=FG5jm7bUE0adThi2ob
export secret_key=Rgd9DI0,[i5%T@u=V
minio server -C /home/minio/.minio --quiet  /export1
```
IAM sub-system initialization fails
```
API: SYSTEM()
Time: 13:59:08 UTC 04/01/2022
DeploymentID: 55e9b21c-c811-43e7-a61f-ca93c3ed0bca
Error: IAM sub-system is partially initialized, some users may not be available (*errors.errorString)
```
GET on /minio/admin/v3/list-users hang

## Context
Unexpected listing behavior

## Regression
Not sure.

## Your Environment
Master and previous versions




Discussion / hints:
The correct way to get out of this is purge all the .minio.sys/config/iam 

Also changing access credentials has no bearing on the failure to load users. 

Looks like you have an old release locally and you never really migrated properly.

Fix patch:
diff --git a/cmd/admin-handlers-users.go b/cmd/admin-handlers-users.go
index 43e8ef543993a..b4d4fd751a4ad 100644
--- a/cmd/admin-handlers-users.go
+++ b/cmd/admin-handlers-users.go
@@ -90,7 +90,7 @@ func (a adminAPIHandlers) ListBucketUsers(w http.ResponseWriter, r *http.Request
 
 	password := cred.SecretKey
 
-	allCredentials, err := globalIAMSys.ListBucketUsers(bucket)
+	allCredentials, err := globalIAMSys.ListBucketUsers(ctx, bucket)
 	if err != nil {
 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 		return
@@ -124,7 +124,7 @@ func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) {
 
 	password := cred.SecretKey
 
-	allCredentials, err := globalIAMSys.ListUsers()
+	allCredentials, err := globalIAMSys.ListUsers(ctx)
 	if err != nil {
 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 		return
diff --git a/cmd/iam.go b/cmd/iam.go
index a30e2dfb97c8a..7842c77d130f8 100644
--- a/cmd/iam.go
+++ b/cmd/iam.go
@@ -537,9 +537,12 @@ func (sys *IAMSys) ListPolicies(ctx context.Context, bucketName string) (map[str
 		return nil, errServerNotInitialized
 	}
 
-	<-sys.configLoaded
-
-	return sys.store.ListPolicies(ctx, bucketName)
+	select {
+	case <-sys.configLoaded:
+		return sys.store.ListPolicies(ctx, bucketName)
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
 }
 
 // SetPolicy - sets a new named policy.
@@ -672,25 +675,30 @@ func (sys *IAMSys) SetTempUser(ctx context.Context, accessKey string, cred auth.
 }
 
 // ListBucketUsers - list all users who can access this 'bucket'
-func (sys *IAMSys) ListBucketUsers(bucket string) (map[string]madmin.UserInfo, error) {
+func (sys *IAMSys) ListBucketUsers(ctx context.Context, bucket string) (map[string]madmin.UserInfo, error) {
 	if !sys.Initialized() {
 		return nil, errServerNotInitialized
 	}
 
-	<-sys.configLoaded
-
-	return sys.store.GetBucketUsers(bucket)
+	select {
+	case <-sys.configLoaded:
+		return sys.store.GetBucketUsers(bucket)
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
 }
 
 // ListUsers - list all users.
-func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) {
+func (sys *IAMSys) ListUsers(ctx context.Context) (map[string]madmin.UserInfo, error) {
 	if !sys.Initialized() {
 		return nil, errServerNotInitialized
 	}
-
-	<-sys.configLoaded
-
-	return sys.store.GetUsers(), nil
+	select {
+	case <-sys.configLoaded:
+		return sys.store.GetUsers(), nil
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
 }
 
 // IsTempUser - returns if given key is a temporary user.
@@ -886,9 +894,12 @@ func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([
 		return nil, errServerNotInitialized
 	}
 
-	<-sys.configLoaded
-
-	return sys.store.ListServiceAccounts(ctx, accessKey)
+	select {
+	case <-sys.configLoaded:
+		return sys.store.ListServiceAccounts(ctx, accessKey)
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
 }
 
 // GetServiceAccount - wrapper method to get information about a service account
@@ -1288,9 +1299,12 @@ func (sys *IAMSys) ListGroups(ctx context.Context) (r []string, err error) {
 		return r, errServerNotInitialized
 	}
 
-	<-sys.configLoaded
-
-	return sys.store.ListGroups(ctx)
+	select {
+	case <-sys.configLoaded:
+		return sys.store.ListGroups(ctx)
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
 }
 
 // PolicyDBSet - sets a policy for a user or group in the PolicyDB.
diff --git a/cmd/site-replication.go b/cmd/site-replication.go
index 1c69d4e143b11..dbf58f33f7ab5 100644
--- a/cmd/site-replication.go
+++ b/cmd/site-replication.go
@@ -2892,7 +2892,7 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
 			}
 		} else {
 			//  get users/group info on local.
-			userInfoMap, errU := globalIAMSys.ListUsers()
+			userInfoMap, errU := globalIAMSys.ListUsers(ctx)
 			if errU != nil {
 				return info, errSRBackendIssue(errU)
 			}


Test patch: