From 9534aabf159dd54485238233ad2a33fdcb3da3cc Mon Sep 17 00:00:00 2001 From: "Kyle M. Tarplee" Date: Tue, 19 Sep 2023 17:49:15 -0400 Subject: [PATCH] fix: do not copy sync.Mutex in Repository sibling() was copying the entire Respoitory struct which contains a sync.Mutex. Added a clone() to consolidate the code that performs a limited copy. Signed-off-by: Kyle M. Tarplee --- registry/remote/repository.go | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/registry/remote/repository.go b/registry/remote/repository.go index 337b4115..00335047 100644 --- a/registry/remote/repository.go +++ b/registry/remote/repository.go @@ -147,7 +147,7 @@ type Repository struct { // - https://www.rfc-editor.org/rfc/rfc7234#section-5.5 HandleWarning func(warning Warning) - // NOTE: Must keep fields in sync with newRepositoryWithOptions function. + // NOTE: Must keep fields in sync with clone(). // referrersState represents that if the repository supports Referrers API. // default: referrersStateUnknown @@ -186,16 +186,23 @@ func newRepositoryWithOptions(ref registry.Reference, opts *RepositoryOptions) ( if err := ref.ValidateRepository(); err != nil { return nil, err } + repo := (*Repository)(opts).clone() + repo.Reference = ref + return repo, nil +} + +// clone makes a copy of the Repository being careful not to copy non-copyable fields (sync.Mutex and syncutil.Pool types) +func (r *Repository) clone() *Repository { return &Repository{ - Client: opts.Client, - Reference: ref, - PlainHTTP: opts.PlainHTTP, - SkipReferrersGC: opts.SkipReferrersGC, - ManifestMediaTypes: slices.Clone(opts.ManifestMediaTypes), - TagListPageSize: opts.TagListPageSize, - ReferrerListPageSize: opts.ReferrerListPageSize, - MaxMetadataBytes: opts.MaxMetadataBytes, - }, nil + Client: r.Client, + Reference: r.Reference, + PlainHTTP: r.PlainHTTP, + SkipReferrersGC: r.SkipReferrersGC, + ManifestMediaTypes: slices.Clone(r.ManifestMediaTypes), + TagListPageSize: r.TagListPageSize, + ReferrerListPageSize: r.ReferrerListPageSize, + MaxMetadataBytes: r.MaxMetadataBytes, + } } // SetReferrersCapability indicates the Referrers API capability of the remote @@ -803,10 +810,10 @@ func (s *blobStore) Mount(ctx context.Context, desc ocispec.Descriptor, fromRepo // sibling returns a blob store for another repository in the same // registry. func (s *blobStore) sibling(otherRepoName string) *blobStore { - otherRepo := *s.repo + otherRepo := s.repo.clone() otherRepo.Reference.Repository = otherRepoName return &blobStore{ - repo: &otherRepo, + repo: otherRepo, } }