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
+43 -21
View File
@@ -1031,34 +1031,56 @@ func (a adminAPIHandlers) ImportBucketMetadataHandler(w http.ResponseWriter, r *
if len(fields) == 0 { if len(fields) == 0 {
continue continue
} }
lockCtx, unlock, err := lockBucketMetadata(ctx, objectAPI, bucket) var merged BucketMetadata
if err != nil { err := func() error {
rpt.SetStatus(bucket, "", err) lockCtx, unlock, err := lockBucketMetadata(ctx, objectAPI, bucket)
continue if err != nil {
} return err
merged, err := loadBucketMetadataParse(lockCtx, objectAPI, bucket, true) }
if err == nil { defer unlock()
merged, err = loadBucketMetadataParse(lockCtx, objectAPI, bucket, true)
if err != nil {
return err
}
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
} }