Avoid showing buckets without quorum in each pool (#18125)

This commit is contained in:
Anis Eleuch 2023-09-29 00:58:54 -07:00 committed by GitHub
parent e101eeeda9
commit aec023f537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 20 deletions

View File

@ -23,6 +23,7 @@ import (
"errors" "errors"
"io" "io"
"net/url" "net/url"
"sort"
"strconv" "strconv"
xhttp "github.com/minio/minio/internal/http" xhttp "github.com/minio/minio/internal/http"
@ -123,8 +124,10 @@ func NewS3PeerSys(endpoints EndpointServerPools) *S3PeerSys {
} }
} }
// ListBuckets lists buckets across all servers and returns a possible consistent view // ListBuckets lists buckets across all nodes and returns a consistent view:
func (sys *S3PeerSys) ListBuckets(ctx context.Context, opts BucketOptions) (result []BucketInfo, err error) { // - Return an error when a pool cannot return N/2+1 valid bucket information
// - For each pool, check if the bucket exists in N/2+1 nodes before including it in the final result
func (sys *S3PeerSys) ListBuckets(ctx context.Context, opts BucketOptions) ([]BucketInfo, error) {
g := errgroup.WithNErrs(len(sys.peerClients)) g := errgroup.WithNErrs(len(sys.peerClients))
nodeBuckets := make([][]BucketInfo, len(sys.peerClients)) nodeBuckets := make([][]BucketInfo, len(sys.peerClients))
@ -148,24 +151,51 @@ func (sys *S3PeerSys) ListBuckets(ctx context.Context, opts BucketOptions) (resu
errs = append(errs, g.Wait()...) errs = append(errs, g.Wait()...)
quorum := len(sys.peerClients)/2 + 1 // The list of buckets in a map to avoid duplication
if err = reduceReadQuorumErrs(ctx, errs, bucketOpIgnoredErrs, quorum); err != nil { resultMap := make(map[string]BucketInfo)
return nil, err
for poolIdx := 0; poolIdx < sys.poolsCount; poolIdx++ {
perPoolErrs := make([]error, 0, len(sys.peerClients))
for i, client := range sys.peerClients {
if slices.Contains(client.GetPools(), poolIdx) {
perPoolErrs = append(perPoolErrs, errs[i])
}
}
quorum := len(perPoolErrs)/2 + 1
if poolErr := reduceWriteQuorumErrs(ctx, perPoolErrs, bucketOpIgnoredErrs, quorum); poolErr != nil {
return nil, poolErr
} }
bucketsMap := make(map[string]struct{}) bucketsMap := make(map[string]int)
for idx, buckets := range nodeBuckets { for idx, buckets := range nodeBuckets {
if errs[idx] != nil { if buckets == nil {
continue
}
if !slices.Contains(sys.peerClients[idx].GetPools(), poolIdx) {
continue continue
} }
for _, bi := range buckets { for _, bi := range buckets {
_, ok := bucketsMap[bi.Name] _, ok := resultMap[bi.Name]
if !ok { if ok {
bucketsMap[bi.Name] = struct{}{} // Skip it, this bucket is found in another pool
continue
}
bucketsMap[bi.Name]++
if bucketsMap[bi.Name] == quorum {
resultMap[bi.Name] = bi
}
}
}
}
result := make([]BucketInfo, 0, len(resultMap))
for _, bi := range resultMap {
result = append(result, bi) result = append(result, bi)
} }
}
} sort.Slice(result, func(i, j int) bool {
return result[i].Name < result[j].Name
})
return result, nil return result, nil
} }

View File

@ -22,7 +22,6 @@ import (
"encoding/gob" "encoding/gob"
"errors" "errors"
"net/http" "net/http"
"sort"
"github.com/minio/minio/internal/logger" "github.com/minio/minio/internal/logger"
"github.com/minio/mux" "github.com/minio/mux"
@ -124,10 +123,6 @@ func listBucketsLocal(ctx context.Context, opts BucketOptions) (buckets []Bucket
} }
} }
sort.Slice(buckets, func(i, j int) bool {
return buckets[i].Name < buckets[j].Name
})
return buckets, nil return buckets, nil
} }