Skip to content

Commit b558f59

Browse files
abushwangsondavidb
authored andcommitted
fix fscache not cleanup
Signed-off-by: Shubhranshu Mahapatra <shubhum@amazon.com> Signed-off-by: abushwang <abushwang@tencent.com>
1 parent a4806a4 commit b558f59

7 files changed

Lines changed: 62 additions & 18 deletions

File tree

fs/fs.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,8 +1229,13 @@ func (fs *filesystem) Unmount(ctx context.Context, mountpoint string) error {
12291229
delete(fs.layer, mountpoint)
12301230
// If the mountpoint is an id-mapped layer, it is pointing to the
12311231
// underlying layer, so we cannot call done on it.
1232+
// We do a evict call to call the registered evict functions.
1233+
// This cleans up layer resources and removes it from the resolver cache,
1234+
// preparing the layer for removal and freeing associated memory done on
1235+
// call of the finalizer in span manager
12321236
if !isIDMappedDir(mountpoint) {
12331237
l.Done()
1238+
fs.resolver.Evict(l.GetCacheRefKey())
12341239
}
12351240
fs.layerMu.Unlock()
12361241
fs.metricsController.Remove(mountpoint)

fs/fs_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ func (l *breakableLayer) SkipVerify() {}
9595
func (l *breakableLayer) ReadAt([]byte, int64, ...remote.Option) (int, error) {
9696
return 0, fmt.Errorf("fail")
9797
}
98+
func (l *breakableLayer) GetCacheRefKey() string { return "" }
9899
func (l *breakableLayer) BackgroundFetch() error { return fmt.Errorf("fail") }
99100
func (l *breakableLayer) Check() error {
100101
if !l.success {

fs/layer/layer.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ type Layer interface {
104104
// Done releases the reference to this layer. The resources related to this layer will be
105105
// discarded sooner or later. Queries after calling this function won't be serviced.
106106
Done()
107+
108+
// GetCacheRefKey returns the reference key for the cache used by the layer
109+
GetCacheRefKey() string
107110
}
108111

109112
// Info is the current status of a layer.
@@ -226,6 +229,12 @@ func newCache(root string, cacheType string, cfg config.FSConfig) (cache.BlobCac
226229
)
227230
}
228231

232+
func (r *Resolver) Evict(name string) {
233+
r.layerCacheMu.Lock()
234+
r.layerCache.Remove(name)
235+
r.layerCacheMu.Unlock()
236+
}
237+
229238
// Resolve resolves a layer based on the passed layer blob information.
230239
func (r *Resolver) Resolve(ctx context.Context, hosts []docker.RegistryHost, refspec reference.Spec, desc, sociDesc ocispec.Descriptor, opCounter *FuseOperationCounter, disableVerification bool, metadataOpts ...metadata.Option) (_ Layer, retErr error) {
231240
name := refspec.String() + "/" + desc.Digest.String()
@@ -339,7 +348,7 @@ func (r *Resolver) Resolve(ctx context.Context, hosts []docker.RegistryHost, ref
339348
}
340349
disableXAttrs := getDisableXAttrAnnotation(sociDesc)
341350
// Combine layer information together and cache it.
342-
l := newLayer(r, desc, blobR, vr, bgLayerResolver, opCounter, disableXAttrs)
351+
l := newLayer(r, desc, name, blobR, vr, bgLayerResolver, opCounter, disableXAttrs)
343352
r.layerCacheMu.Lock()
344353
cachedL, done2, added := r.layerCache.Add(name, l)
345354
r.layerCacheMu.Unlock()
@@ -370,18 +379,8 @@ func (r *Resolver) resolveBlob(ctx context.Context, hosts []docker.RegistryHost,
370379
r.blobCacheMu.Unlock()
371380
}
372381

373-
httpCache, err := newCache(filepath.Join(r.rootDir, "httpcache"), r.config.HTTPCacheType, r.config)
374-
if err != nil {
375-
return nil, fmt.Errorf("failed to create http cache: %w", err)
376-
}
377-
defer func() {
378-
if retErr != nil {
379-
httpCache.Close()
380-
}
381-
}()
382-
383382
// Resolve the blob and cache the result.
384-
b, err := r.resolver.Resolve(ctx, hosts, refspec, desc, httpCache)
383+
b, err := r.resolver.Resolve(ctx, hosts, refspec, desc)
385384
if err != nil {
386385
return nil, fmt.Errorf("failed to resolve the source: %w", err)
387386
}
@@ -397,6 +396,7 @@ func (r *Resolver) resolveBlob(ctx context.Context, hosts []docker.RegistryHost,
397396
func newLayer(
398397
resolver *Resolver,
399398
desc ocispec.Descriptor,
399+
cacheRefKey string,
400400
blob *blobRef,
401401
r reader.Reader,
402402
bgResolver backgroundfetcher.Resolver,
@@ -406,6 +406,7 @@ func newLayer(
406406
return &layer{
407407
resolver: resolver,
408408
desc: desc,
409+
cacheRefKey: cacheRefKey,
409410
blob: blob,
410411
r: r,
411412
bgResolver: bgResolver,
@@ -415,9 +416,10 @@ func newLayer(
415416
}
416417

417418
type layer struct {
418-
resolver *Resolver
419-
desc ocispec.Descriptor
420-
blob *blobRef
419+
resolver *Resolver
420+
desc ocispec.Descriptor
421+
cacheRefKey string
422+
blob *blobRef
421423

422424
bgResolver backgroundfetcher.Resolver
423425

@@ -430,6 +432,10 @@ type layer struct {
430432
closedMu sync.Mutex
431433
}
432434

435+
func (l *layer) GetCacheRefKey() string {
436+
return l.cacheRefKey
437+
}
438+
433439
func (l *layer) Info() Info {
434440
return Info{
435441
Digest: l.desc.Digest,

fs/reader/reader.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ func (gr *reader) Close() (retErr error) {
128128
return nil
129129
}
130130
gr.closed = true
131+
if gr.spanManager != nil {
132+
gr.spanManager.Close()
133+
}
131134
if err := gr.r.Close(); err != nil {
132135
retErr = errors.Join(retErr, err)
133136
}

fs/remote/resolver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func NewResolver(cfg config.BlobConfig, handlers map[string]Handler) *Resolver {
9797
}
9898
}
9999

100-
func (r *Resolver) Resolve(ctx context.Context, hosts []docker.RegistryHost, refspec reference.Spec, desc ocispec.Descriptor, blobCache cache.BlobCache) (Blob, error) {
100+
func (r *Resolver) Resolve(ctx context.Context, hosts []docker.RegistryHost, refspec reference.Spec, desc ocispec.Descriptor) (Blob, error) {
101101

102102
var (
103103
validInterval = time.Duration(r.blobConfig.ValidInterval) * time.Second

fs/span-manager/span_manager.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"fmt"
2424
"io"
2525
"runtime"
26+
"sync"
2627

2728
"github.com/awslabs/soci-snapshotter/cache"
2829
"github.com/awslabs/soci-snapshotter/util/ioutils"
@@ -49,6 +50,7 @@ type SpanManager struct {
4950
spans []*span
5051
ztoc *ztoc.Ztoc
5152
maxSpanVerificationFailureRetries int
53+
closeOnce sync.Once
5254
}
5355

5456
type spanInfo struct {
@@ -432,6 +434,13 @@ func (m *SpanManager) verifySpanContents(compressedData []byte, spanID compressi
432434

433435
// Close closes both the underlying zinfo data and blob cache.
434436
func (m *SpanManager) Close() {
435-
m.zinfo.Close()
436-
m.cache.Close()
437+
m.closeOnce.Do(func() {
438+
log.L.Debug("Spancache finalizer called. Cleaning up spancache")
439+
if m.zinfo != nil {
440+
m.zinfo.Close()
441+
}
442+
if m.cache != nil {
443+
m.cache.Close()
444+
}
445+
})
437446
}

snapshot/snapshot.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,26 @@ func (o *snapshotter) restoreRemoteSnapshot(ctx context.Context) error {
11181118
return err
11191119
}
11201120
for _, info := range task {
1121+
if err := func() error {
1122+
ctx, t, err := o.ms.TransactionContext(ctx, false)
1123+
if err != nil {
1124+
return err
1125+
}
1126+
defer t.Rollback()
1127+
id, _, _, err := storage.GetInfo(ctx, info.Name)
1128+
if err != nil {
1129+
return err
1130+
}
1131+
if err := os.Mkdir(filepath.Join(o.root, "snapshots", id), 0700); err != nil && !os.IsExist(err) {
1132+
return err
1133+
}
1134+
if err := os.Mkdir(o.upperPath(id), 0755); err != nil && !os.IsExist(err) {
1135+
return err
1136+
}
1137+
return nil
1138+
}(); err != nil {
1139+
return fmt.Errorf("failed to create remote snapshot directory: %s: %w", info.Name, err)
1140+
}
11211141
ns, ok := info.Labels[source.TargetNamespace]
11221142
if !ok {
11231143
return ErrNoNamespace

0 commit comments

Comments
 (0)