Skip to content

Commit 72577aa

Browse files
committed
Integrate the temporary directory into layer deletion
This enables deferred deletion of physical files outside of global locks, improving performance and reducing lock contention. Signed-off-by: Jan Rodák <[email protected]>
1 parent 894e80c commit 72577aa

File tree

11 files changed

+279
-37
lines changed

11 files changed

+279
-37
lines changed

drivers/aufs/aufs.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"time"
3737

3838
graphdriver "github.com/containers/storage/drivers"
39+
"github.com/containers/storage/internal/tempdir"
3940
"github.com/containers/storage/pkg/archive"
4041
"github.com/containers/storage/pkg/chrootarchive"
4142
"github.com/containers/storage/pkg/directory"
@@ -781,3 +782,14 @@ func (a *Driver) SupportsShifting(uidmap, gidmap []idtools.IDMap) bool {
781782
func (a *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
782783
return graphdriver.DedupResult{}, nil
783784
}
785+
786+
// DeferredRemove is not implemented.
787+
// It calls Remove directly.
788+
func (a *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
789+
return nil, a.Remove(id)
790+
}
791+
792+
// GetTempDirRootDir is not implemented.
793+
func (a *Driver) GetTempDirRootDir() string {
794+
return ""
795+
}

drivers/btrfs/btrfs.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"unsafe"
3131

3232
graphdriver "github.com/containers/storage/drivers"
33+
"github.com/containers/storage/internal/tempdir"
3334
"github.com/containers/storage/pkg/directory"
3435
"github.com/containers/storage/pkg/fileutils"
3536
"github.com/containers/storage/pkg/idtools"
@@ -678,3 +679,14 @@ func (d *Driver) AdditionalImageStores() []string {
678679
func (d *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
679680
return graphdriver.DedupResult{}, nil
680681
}
682+
683+
// DeferredRemove is not implemented.
684+
// It calls Remove directly.
685+
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
686+
return nil, d.Remove(id)
687+
}
688+
689+
// GetTempDirRootDir is not implemented.
690+
func (d *Driver) GetTempDirRootDir() string {
691+
return ""
692+
}

drivers/driver.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"strings"
1010

1111
"github.com/containers/storage/internal/dedup"
12+
"github.com/containers/storage/internal/tempdir"
1213
"github.com/containers/storage/pkg/archive"
1314
"github.com/containers/storage/pkg/directory"
1415
"github.com/containers/storage/pkg/fileutils"
@@ -124,6 +125,13 @@ type ProtoDriver interface {
124125
CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *CreateOpts, readWrite bool) error
125126
// Remove attempts to remove the filesystem layer with this id.
126127
Remove(id string) error
128+
// DeferredRemove is used to remove the filesystem layer with this id.
129+
// This removal happen immediately (the layer is no longer usable),
130+
// but physically deleting the files may be deferred.
131+
// Caller MUST call returned Cleanup function.
132+
DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error)
133+
// GetTempDirRootDir returns the root directory for temporary directories.
134+
GetTempDirRootDir() string
127135
// Get returns the mountpoint for the layered filesystem referred
128136
// to by this id. You can optionally specify a mountLabel or "".
129137
// Optionally it gets the mappings used to create the layer.

drivers/overlay/overlay.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/containers/storage/drivers/quota"
2525
"github.com/containers/storage/internal/dedup"
2626
"github.com/containers/storage/internal/staging_lockfile"
27+
"github.com/containers/storage/internal/tempdir"
2728
"github.com/containers/storage/pkg/archive"
2829
"github.com/containers/storage/pkg/chrootarchive"
2930
"github.com/containers/storage/pkg/directory"
@@ -1305,17 +1306,24 @@ func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMa
13051306

13061307
// Remove cleans the directories that are created for this id.
13071308
func (d *Driver) Remove(id string) error {
1309+
return d.removeCommon(id, func(path string) error {
1310+
return system.EnsureRemoveAll(path)
1311+
})
1312+
}
1313+
1314+
func (d *Driver) removeCommon(id string, cleanup func(string) error) error {
13081315
dir := d.dir(id)
13091316
lid, err := os.ReadFile(path.Join(dir, "link"))
13101317
if err == nil {
1311-
if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil {
1318+
linkPath := path.Join(d.home, linkDir, string(lid))
1319+
if err := cleanup(linkPath); err != nil {
13121320
logrus.Debugf("Failed to remove link: %v", err)
13131321
}
13141322
}
13151323

13161324
d.releaseAdditionalLayerByID(id)
13171325

1318-
if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) {
1326+
if err := cleanup(dir); err != nil && !os.IsNotExist(err) {
13191327
return err
13201328
}
13211329
if d.quotaCtl != nil {
@@ -1327,6 +1335,24 @@ func (d *Driver) Remove(id string) error {
13271335
return nil
13281336
}
13291337

1338+
func (d *Driver) GetTempDirRootDir() string {
1339+
return filepath.Join(d.home, stagingDir)
1340+
}
1341+
1342+
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
1343+
t, err := tempdir.NewTempDir(d.GetTempDirRootDir())
1344+
if err != nil {
1345+
return nil, err
1346+
}
1347+
1348+
if err := d.removeCommon(id, func(path string) error {
1349+
return t.Add(path)
1350+
}); err != nil {
1351+
return t.Cleanup, fmt.Errorf("failed to add to stage directory: %w", err)
1352+
}
1353+
return t.Cleanup, nil
1354+
}
1355+
13301356
// recreateSymlinks goes through the driver's home directory and checks if the diff directory
13311357
// under each layer has a symlink created for it under the linkDir. If the symlink does not
13321358
// exist, it creates them
@@ -1353,8 +1379,8 @@ func (d *Driver) recreateSymlinks() error {
13531379
// Check that for each layer, there's a link in "l" with the name in
13541380
// the layer's "link" file that points to the layer's "diff" directory.
13551381
for _, dir := range dirs {
1356-
// Skip over the linkDir and anything that is not a directory
1357-
if dir.Name() == linkDir || !dir.IsDir() {
1382+
// Skip over the linkDir and anything that is not a directory or tempDir
1383+
if dir.Name() == linkDir || !dir.IsDir() || dir.Name() == stagingDir {
13581384
continue
13591385
}
13601386
// Read the "link" file under each layer to get the name of the symlink

drivers/vfs/driver.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
graphdriver "github.com/containers/storage/drivers"
1313
"github.com/containers/storage/internal/dedup"
14+
"github.com/containers/storage/internal/tempdir"
1415
"github.com/containers/storage/pkg/archive"
1516
"github.com/containers/storage/pkg/directory"
1617
"github.com/containers/storage/pkg/fileutils"
@@ -244,6 +245,21 @@ func (d *Driver) Remove(id string) error {
244245
return system.EnsureRemoveAll(d.dir(id))
245246
}
246247

248+
func (d *Driver) GetTempDirRootDir() string {
249+
return filepath.Join(d.home, "tempdirs")
250+
}
251+
252+
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
253+
t, err := tempdir.NewTempDir(d.GetTempDirRootDir())
254+
if err != nil {
255+
return nil, err
256+
}
257+
if err := t.Add(d.dir(id)); err != nil {
258+
return nil, err
259+
}
260+
return t.Cleanup, nil
261+
}
262+
247263
// Get returns the directory for the given id.
248264
func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) {
249265
dir := d.dir(id)

drivers/windows/windows.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/Microsoft/go-winio/backuptar"
2525
"github.com/Microsoft/hcsshim"
2626
graphdriver "github.com/containers/storage/drivers"
27+
"github.com/containers/storage/internal/tempdir"
2728
"github.com/containers/storage/pkg/archive"
2829
"github.com/containers/storage/pkg/directory"
2930
"github.com/containers/storage/pkg/fileutils"
@@ -1014,3 +1015,14 @@ func parseStorageOpt(storageOpt map[string]string) (*storageOptions, error) {
10141015
}
10151016
return &options, nil
10161017
}
1018+
1019+
// DeferredRemove is not implemented.
1020+
// It calls Remove directly.
1021+
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
1022+
return nil, d.Remove(id)
1023+
}
1024+
1025+
// GetTempDirRootDir is not implemented.
1026+
func (d *Driver) GetTempDirRootDir() string {
1027+
return ""
1028+
}

drivers/zfs/zfs.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"time"
1414

1515
graphdriver "github.com/containers/storage/drivers"
16+
"github.com/containers/storage/internal/tempdir"
1617
"github.com/containers/storage/pkg/directory"
1718
"github.com/containers/storage/pkg/idtools"
1819
"github.com/containers/storage/pkg/mount"
@@ -406,6 +407,12 @@ func (d *Driver) Remove(id string) error {
406407
return nil
407408
}
408409

410+
// DeferredRemove is not implemented.
411+
// It calls Remove directly.
412+
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
413+
return nil, d.Remove(id)
414+
}
415+
409416
// Get returns the mountpoint for the given id after creating the target directories if necessary.
410417
func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) {
411418
mountpoint := d.mountPath(id)
@@ -516,3 +523,8 @@ func (d *Driver) AdditionalImageStores() []string {
516523
func (d *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
517524
return graphdriver.DedupResult{}, nil
518525
}
526+
527+
// GetTempDirRootDir is not implemented.
528+
func (d *Driver) GetTempDirRootDir() string {
529+
return ""
530+
}

0 commit comments

Comments
 (0)