diff --git a/cmd/bucket-lifecycle.go b/cmd/bucket-lifecycle.go index 305c3ddb3..4e4d97c9e 100644 --- a/cmd/bucket-lifecycle.go +++ b/cmd/bucket-lifecycle.go @@ -340,13 +340,14 @@ func transitionObject(ctx context.Context, objectAPI ObjectLayer, objInfo Object return err } oi := gr.ObjInfo - if oi.TransitionStatus == lifecycle.TransitionComplete { + gr.Close() // make sure to avoid leaks. return nil } putOpts := putTransitionOpts(oi) if _, err = tgt.PutObject(ctx, arn.Bucket, oi.Name, gr, oi.Size, "", "", putOpts); err != nil { + gr.Close() // make sure to avoid leaks. return err } gr.Close() diff --git a/cmd/bucket-replication.go b/cmd/bucket-replication.go index c3f6e428a..59ae32ae4 100644 --- a/cmd/bucket-replication.go +++ b/cmd/bucket-replication.go @@ -441,37 +441,42 @@ func replicateObject(ctx context.Context, objInfo ObjectInfo, objectAPI ObjectLa } } - target, err := globalBucketMetadataSys.GetBucketTarget(bucket, cfg.RoleArn) - if err != nil { - logger.LogIf(ctx, fmt.Errorf("failed to get target for replication bucket:%s cfg:%s err:%s", bucket, cfg.RoleArn, err)) - return - } - putOpts := putReplicationOpts(ctx, dest, objInfo) replicationStatus := replication.Complete + if rtype != replicateAll { + gr.Close() - // Setup bandwidth throttling - peers, _ := globalEndpoints.peers() - totalNodesCount := len(peers) - if totalNodesCount == 0 { - totalNodesCount = 1 // For standalone erasure coding - } - b := target.BandwidthLimit / int64(totalNodesCount) - var headerSize int - for k, v := range putOpts.Header() { - headerSize += len(k) + len(v) - } - r := bandwidth.NewMonitoredReader(ctx, globalBucketMonitor, objInfo.Bucket, objInfo.Name, gr, headerSize, b, target.BandwidthLimit) - if rtype == replicateAll { - _, err = tgt.PutObject(ctx, dest.Bucket, object, r, size, "", "", putOpts) - } else { // replicate metadata for object tagging/copy with metadata replacement dstOpts := miniogo.PutObjectOptions{Internal: miniogo.AdvancedPutOptions{SourceVersionID: objInfo.VersionID}} _, err = tgt.CopyObject(ctx, dest.Bucket, object, dest.Bucket, object, getCopyObjMetadata(objInfo, dest), dstOpts) - } + if err != nil { + replicationStatus = replication.Failed + } + } else { + target, err := globalBucketMetadataSys.GetBucketTarget(bucket, cfg.RoleArn) + if err != nil { + logger.LogIf(ctx, fmt.Errorf("failed to get target for replication bucket:%s cfg:%s err:%s", bucket, cfg.RoleArn, err)) + gr.Close() + return + } - r.Close() - if err != nil { - replicationStatus = replication.Failed + putOpts := putReplicationOpts(ctx, dest, objInfo) + // Setup bandwidth throttling + peers, _ := globalEndpoints.peers() + totalNodesCount := len(peers) + if totalNodesCount == 0 { + totalNodesCount = 1 // For standalone erasure coding + } + b := target.BandwidthLimit / int64(totalNodesCount) + var headerSize int + for k, v := range putOpts.Header() { + headerSize += len(k) + len(v) + } + r := bandwidth.NewMonitoredReader(ctx, globalBucketMonitor, objInfo.Bucket, objInfo.Name, gr, headerSize, b, target.BandwidthLimit) + _, err = tgt.PutObject(ctx, dest.Bucket, object, r, size, "", "", putOpts) + if err != nil { + replicationStatus = replication.Failed + } + r.Close() } objInfo.UserDefined[xhttp.AmzBucketReplicationStatus] = replicationStatus.String() if objInfo.UserTags != "" { diff --git a/cmd/bucket-targets.go b/cmd/bucket-targets.go index f52546564..36d7d8009 100644 --- a/cmd/bucket-targets.go +++ b/cmd/bucket-targets.go @@ -68,7 +68,6 @@ func (sys *BucketTargetSys) ListTargets(ctx context.Context, bucket, arnType str // ListBucketTargets - gets list of bucket targets for this bucket. func (sys *BucketTargetSys) ListBucketTargets(ctx context.Context, bucket string) (*madmin.BucketTargets, error) { - sys.RLock() defer sys.RUnlock() @@ -130,9 +129,13 @@ func (sys *BucketTargetSys) SetTarget(ctx context.Context, bucket string, tgt *m sys.Lock() defer sys.Unlock() - tgts := sys.targetsMap[bucket] + tgts, ok := sys.targetsMap[bucket] + if !ok { + return BucketRemoteTargetNotFound{Bucket: bucket} + } + newtgts := make([]madmin.BucketTarget, len(tgts)) - labels := make(map[string]struct{}) + labels := make(map[string]struct{}, len(tgts)) found := false for idx, t := range tgts { labels[t.Label] = struct{}{} @@ -198,9 +201,12 @@ func (sys *BucketTargetSys) RemoveTarget(ctx context.Context, bucket, arnStr str // delete ARN type from list of matching targets sys.Lock() defer sys.Unlock() - targets := make([]madmin.BucketTarget, 0) found := false - tgts := sys.targetsMap[bucket] + tgts, ok := sys.targetsMap[bucket] + if !ok { + return BucketRemoteTargetNotFound{Bucket: bucket} + } + targets := make([]madmin.BucketTarget, 0, len(tgts)) for _, tgt := range tgts { if tgt.Arn != arnStr { targets = append(targets, tgt)