fix: limit imported metadata replication to changed fields

Release metadata.lock with defer and dispatch only the configuration types actually present in the import. Avoid stamping unrelated peer metadata with the import timestamp.\n\nRefs: #102

Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-09-02 01:16:02 +08:00
parent 10f3a8590b
commit 11de51ec26
+40 -18
View File
@@ -1031,34 +1031,56 @@ func (a adminAPIHandlers) ImportBucketMetadataHandler(w http.ResponseWriter, r *
if len(fields) == 0 { if len(fields) == 0 {
continue continue
} }
var merged BucketMetadata
err := func() error {
lockCtx, unlock, err := lockBucketMetadata(ctx, objectAPI, bucket) lockCtx, unlock, err := lockBucketMetadata(ctx, objectAPI, bucket)
if err != nil { if err != nil {
rpt.SetStatus(bucket, "", err) return err
continue }
defer unlock()
merged, err = loadBucketMetadataParse(lockCtx, objectAPI, bucket, true)
if err != nil {
return err
} }
merged, err := loadBucketMetadataParse(lockCtx, objectAPI, bucket, true)
if err == nil {
applyImportedBucketMetadata(&merged, *meta, fields) applyImportedBucketMetadata(&merged, *meta, fields)
err = globalBucketMetadataSys.saveMetadata(lockCtx, objectAPI, merged) return globalBucketMetadataSys.saveMetadata(lockCtx, objectAPI, merged)
} }()
unlock()
if err != nil { if err != nil {
rpt.SetStatus(bucket, "", err) rpt.SetStatus(bucket, "", err)
continue continue
} }
*meta = merged *meta = merged
globalNotificationSys.LoadBucketMetadata(bgContext(ctx), bucket) globalNotificationSys.LoadBucketMetadata(bgContext(ctx), bucket)
// Call site replication hook. hook := madmin.SRBucketMeta{Bucket: bucket, UpdatedAt: updatedAt}
if err = globalSiteReplicationSys.BucketMetaHook(ctx, madmin.SRBucketMeta{ var hookNeeded bool
Bucket: bucket, if _, ok := fields[bucketQuotaConfigFile]; ok {
Quota: meta.QuotaConfigJSON, hook.Quota = meta.QuotaConfigJSON
Policy: meta.PolicyConfigJSON, hookNeeded = true
Versioning: enc(meta.VersioningConfigXML), }
Tags: enc(meta.TaggingConfigXML), if _, ok := fields[bucketPolicyConfig]; ok {
ObjectLockConfig: enc(meta.ObjectLockConfigXML), hook.Policy = meta.PolicyConfigJSON
SSEConfig: enc(meta.EncryptionConfigXML), hookNeeded = true
UpdatedAt: updatedAt, }
}); err != nil { if _, ok := fields[bucketVersioningConfig]; ok {
hook.Versioning = enc(meta.VersioningConfigXML)
hookNeeded = true
}
if _, ok := fields[bucketTaggingConfig]; ok {
hook.Tags = enc(meta.TaggingConfigXML)
hookNeeded = true
}
if _, ok := fields[objectLockConfig]; ok {
hook.ObjectLockConfig = enc(meta.ObjectLockConfigXML)
hookNeeded = true
}
if _, ok := fields[bucketSSEConfig]; ok {
hook.SSEConfig = enc(meta.EncryptionConfigXML)
hookNeeded = true
}
if hookNeeded {
err = globalSiteReplicationSys.BucketMetaHook(ctx, hook)
}
if err != nil {
rpt.SetStatus(bucket, "", err) rpt.SetStatus(bucket, "", err)
continue continue
} }