From db78431b1ddfd8f2c36b54c2645d28f6a3d9b5ba Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 14 Aug 2024 17:34:56 -0700 Subject: [PATCH] avoid crash when initializing bucket quota cache (#20258) --- cmd/admin-handlers-users.go | 28 ++++++---------------------- cmd/bucket-quota.go | 17 +++++++++-------- cmd/server-main.go | 5 ----- cmd/veeam-sos-api.go | 2 +- 4 files changed, 16 insertions(+), 36 deletions(-) diff --git a/cmd/admin-handlers-users.go b/cmd/admin-handlers-users.go index e7c6d4c25..53b5c173d 100644 --- a/cmd/admin-handlers-users.go +++ b/cmd/admin-handlers-users.go @@ -34,7 +34,6 @@ import ( "github.com/klauspost/compress/zip" "github.com/minio/madmin-go/v3" "github.com/minio/minio/internal/auth" - "github.com/minio/minio/internal/cachevalue" "github.com/minio/minio/internal/config/dns" "github.com/minio/mux" xldap "github.com/minio/pkg/v3/ldap" @@ -1235,18 +1234,6 @@ func (a adminAPIHandlers) AccountInfoHandler(w http.ResponseWriter, r *http.Requ return rd, wr } - bucketStorageCache.InitOnce(10*time.Second, - cachevalue.Opts{ReturnLastGood: true}, - func(ctx context.Context) (DataUsageInfo, error) { - ctx, done := context.WithTimeout(ctx, 2*time.Second) - defer done() - - return loadDataUsageFromBackend(ctx, objectAPI) - }, - ) - - dataUsageInfo, _ := bucketStorageCache.Get() - // If etcd, dns federation configured list buckets from etcd. var err error var buckets []BucketInfo @@ -1333,15 +1320,12 @@ func (a adminAPIHandlers) AccountInfoHandler(w http.ResponseWriter, r *http.Requ rd, wr := isAllowedAccess(bucket.Name) if rd || wr { // Fetch the data usage of the current bucket - var size uint64 - var objectsCount uint64 - var objectsHist, versionsHist map[string]uint64 - if !dataUsageInfo.LastUpdate.IsZero() { - size = dataUsageInfo.BucketsUsage[bucket.Name].Size - objectsCount = dataUsageInfo.BucketsUsage[bucket.Name].ObjectsCount - objectsHist = dataUsageInfo.BucketsUsage[bucket.Name].ObjectSizesHistogram - versionsHist = dataUsageInfo.BucketsUsage[bucket.Name].ObjectVersionsHistogram - } + bui := globalBucketQuotaSys.GetBucketUsageInfo(ctx, bucket.Name) + size := bui.Size + objectsCount := bui.ObjectsCount + objectsHist := bui.ObjectSizesHistogram + versionsHist := bui.ObjectVersionsHistogram + // Fetch the prefix usage of the current bucket var prefixUsage map[string]uint64 if enablePrefixUsage { diff --git a/cmd/bucket-quota.go b/cmd/bucket-quota.go index b287fe6e3..f50a2d7b2 100644 --- a/cmd/bucket-quota.go +++ b/cmd/bucket-quota.go @@ -50,6 +50,9 @@ func (sys *BucketQuotaSys) Init(objAPI ObjectLayer) { bucketStorageCache.InitOnce(10*time.Second, cachevalue.Opts{ReturnLastGood: true, NoWait: true}, func(ctx context.Context) (DataUsageInfo, error) { + if objAPI == nil { + return DataUsageInfo{}, errServerNotInitialized + } ctx, done := context.WithTimeout(ctx, 2*time.Second) defer done() @@ -59,7 +62,9 @@ func (sys *BucketQuotaSys) Init(objAPI ObjectLayer) { } // GetBucketUsageInfo return bucket usage info for a given bucket -func (sys *BucketQuotaSys) GetBucketUsageInfo(ctx context.Context, bucket string) (BucketUsageInfo, error) { +func (sys *BucketQuotaSys) GetBucketUsageInfo(ctx context.Context, bucket string) BucketUsageInfo { + sys.Init(newObjectLayerFn()) + dui, err := bucketStorageCache.GetWithCtx(ctx) timedout := OperationTimedOut{} if err != nil && !errors.Is(err, context.DeadlineExceeded) && !errors.As(err, &timedout) { @@ -73,10 +78,10 @@ func (sys *BucketQuotaSys) GetBucketUsageInfo(ctx context.Context, bucket string if len(dui.BucketsUsage) > 0 { bui, ok := dui.BucketsUsage[bucket] if ok { - return bui, nil + return bui } } - return BucketUsageInfo{}, nil + return BucketUsageInfo{} } // parseBucketQuota parses BucketQuota from json @@ -118,11 +123,7 @@ func (sys *BucketQuotaSys) enforceQuotaHard(ctx context.Context, bucket string, return BucketQuotaExceeded{Bucket: bucket} } - bui, err := sys.GetBucketUsageInfo(ctx, bucket) - if err != nil { - return err - } - + bui := sys.GetBucketUsageInfo(ctx, bucket) if bui.Size > 0 && ((bui.Size + uint64(size)) >= quotaSize) { return BucketQuotaExceeded{Bucket: bucket} } diff --git a/cmd/server-main.go b/cmd/server-main.go index 92131d6b3..b006f900c 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -1090,11 +1090,6 @@ func serverMain(ctx *cli.Context) { globalSiteReplicationSys.Init(GlobalContext, newObject) }) - // Initialize quota manager. - bootstrapTrace("globalBucketQuotaSys.Init", func() { - globalBucketQuotaSys.Init(newObject) - }) - // Populate existing buckets to the etcd backend if globalDNSConfig != nil { // Background this operation. diff --git a/cmd/veeam-sos-api.go b/cmd/veeam-sos-api.go index 1f360c1b5..33ff9e132 100644 --- a/cmd/veeam-sos-api.go +++ b/cmd/veeam-sos-api.go @@ -171,7 +171,7 @@ func veeamSOSAPIGetObject(ctx context.Context, bucket, object string, rs *HTTPRa } q, _ := globalBucketQuotaSys.Get(ctx, bucket) - binfo, _ := globalBucketQuotaSys.GetBucketUsageInfo(ctx, bucket) + binfo := globalBucketQuotaSys.GetBucketUsageInfo(ctx, bucket) ci := capacityInfo{ Used: int64(binfo.Size),