From a5b35d09b06555ac2842a52c5b9d30d30f3585e4 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 15 Nov 2025 12:24:12 -0800 Subject: [PATCH] s3: Enhanced versioning state tracing for suspended versioning diagnosis Added comprehensive logging across the entire versioning state flow: PutBucketVersioningHandler: - Log requested status (Enabled/Suspended) - Log when calling setBucketVersioningStatus - Log success/failure of status change setBucketVersioningStatus: - Log bucket and status being set - Log when config is updated - Log completion with error code updateBucketConfig: - Log versioning state being written to cache - Immediate cache verification after Set - Log if cache verification fails getVersioningState: - Log bucket name and state being returned - Log if object lock forces VersioningEnabled - Log errors This will reveal: 1. If PutBucketVersioning(Suspended) is reaching the handler 2. If the cache update succeeds 3. What state getVersioningState returns during PUT 4. Any cache consistency issues Expected to show why bucket still reports 'Enabled' after 'Suspended' call. --- weed/s3api/s3api_bucket_config.go | 13 ++++++++++++- weed/s3api/s3api_bucket_handlers.go | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/weed/s3api/s3api_bucket_config.go b/weed/s3api/s3api_bucket_config.go index 3a2ad4841..ad27bf139 100644 --- a/weed/s3api/s3api_bucket_config.go +++ b/weed/s3api/s3api_bucket_config.go @@ -479,8 +479,15 @@ func (s3a *S3ApiServer) updateBucketConfig(bucket string, updateFn func(*BucketC glog.V(3).Infof("updateBucketConfig: saved entry to filer for bucket %s", bucket) // Update cache - glog.V(3).Infof("updateBucketConfig: updating cache for bucket %s, ObjectLockConfig=%+v", bucket, config.ObjectLockConfig) + glog.V(0).Infof("updateBucketConfig: updating cache for bucket %s, Versioning='%s', ObjectLockConfig=%+v", bucket, config.Versioning, config.ObjectLockConfig) s3a.bucketConfigCache.Set(bucket, config) + + // Verify cache update + if cached, found := s3a.bucketConfigCache.Get(bucket); found { + glog.V(0).Infof("updateBucketConfig: cache verification - bucket %s now has Versioning='%s'", bucket, cached.Versioning) + } else { + glog.Errorf("updateBucketConfig: CACHE VERIFICATION FAILED - bucket %s not found in cache after Set", bucket) + } return s3err.ErrNone } @@ -520,17 +527,21 @@ func (s3a *S3ApiServer) getVersioningState(bucket string) (string, error) { config, errCode := s3a.getBucketConfig(bucket) if errCode != s3err.ErrNone { if errCode == s3err.ErrNoSuchBucket { + glog.V(0).Infof("getVersioningState: bucket %s not found", bucket) return "", nil } + glog.Errorf("getVersioningState: failed to get bucket config for %s: %v", bucket, errCode) return "", fmt.Errorf("failed to get bucket config: %v", errCode) } // If object lock is enabled, versioning must be enabled regardless of explicit setting if config.ObjectLockConfig != nil { + glog.V(0).Infof("getVersioningState: bucket %s has object lock, returning VersioningEnabled", bucket) return s3_constants.VersioningEnabled, nil } // Return the explicit versioning status (empty string means never configured) + glog.V(0).Infof("getVersioningState: bucket %s returning versioning state='%s'", bucket, config.Versioning) return config.Versioning, nil } diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go index 5ebb06b21..c1d8230b3 100644 --- a/weed/s3api/s3api_bucket_handlers.go +++ b/weed/s3api/s3api_bucket_handlers.go @@ -1158,13 +1158,16 @@ func (s3a *S3ApiServer) PutBucketVersioningHandler(w http.ResponseWriter, r *htt } status := *versioningConfig.Status + glog.V(0).Infof("PutBucketVersioningHandler: bucket=%s, requested status='%s'", bucket, status) if status != s3_constants.VersioningEnabled && status != s3_constants.VersioningSuspended { + glog.Errorf("PutBucketVersioningHandler: invalid status '%s' for bucket %s", status, bucket) s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest) return } // Check if trying to suspend versioning on a bucket with object lock enabled if status == s3_constants.VersioningSuspended { + glog.V(0).Infof("PutBucketVersioningHandler: attempting to suspend versioning for bucket=%s", bucket) // Get bucket configuration to check for object lock bucketConfig, errCode := s3a.getBucketConfig(bucket) if errCode == s3err.ErrNone && bucketConfig.ObjectLockConfig != nil { @@ -1175,11 +1178,13 @@ func (s3a *S3ApiServer) PutBucketVersioningHandler(w http.ResponseWriter, r *htt } // Update bucket versioning configuration using new bucket config system + glog.V(0).Infof("PutBucketVersioningHandler: calling setBucketVersioningStatus for bucket=%s with status='%s'", bucket, status) if errCode := s3a.setBucketVersioningStatus(bucket, status); errCode != s3err.ErrNone { - glog.Errorf("PutBucketVersioningHandler save config: %d", errCode) + glog.Errorf("PutBucketVersioningHandler save config: bucket=%s, status='%s', errCode=%d", bucket, status, errCode) s3err.WriteErrorResponse(w, r, errCode) return } + glog.V(0).Infof("PutBucketVersioningHandler: successfully set versioning status for bucket=%s to '%s'", bucket, status) writeSuccessResponseEmpty(w, r) }