Skip to content

Introduce a temporary directory for deleting layer files outside the lock #2325

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions drivers/aufs/aufs.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"time"

graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/internal/tempdir"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/directory"
Expand Down Expand Up @@ -781,3 +782,14 @@ func (a *Driver) SupportsShifting(uidmap, gidmap []idtools.IDMap) bool {
func (a *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
return graphdriver.DedupResult{}, nil
}

// DeferredRemove is not implemented.
// It calls Remove directly.
func (a *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
return nil, a.Remove(id)
}

// GetTempDirRootDir is not implemented.
func (a *Driver) GetTempDirRootDir() string {
return ""
}
12 changes: 12 additions & 0 deletions drivers/btrfs/btrfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"unsafe"

graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/internal/tempdir"
"github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/fileutils"
"github.com/containers/storage/pkg/idtools"
Expand Down Expand Up @@ -678,3 +679,14 @@ func (d *Driver) AdditionalImageStores() []string {
func (d *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
return graphdriver.DedupResult{}, nil
}

// DeferredRemove is not implemented.
// It calls Remove directly.
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
return nil, d.Remove(id)
}

// GetTempDirRootDir is not implemented.
func (d *Driver) GetTempDirRootDir() string {
return ""
}
8 changes: 8 additions & 0 deletions drivers/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/containers/storage/internal/dedup"
"github.com/containers/storage/internal/tempdir"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/fileutils"
Expand Down Expand Up @@ -124,6 +125,13 @@ type ProtoDriver interface {
CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *CreateOpts, readWrite bool) error
// Remove attempts to remove the filesystem layer with this id.
Remove(id string) error
// DeferredRemove is used to remove the filesystem layer with this id.
// This removal happen immediately (the layer is no longer usable),
// but physically deleting the files may be deferred.
// Caller MUST call returned Cleanup function.
DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error)
// GetTempDirRootDir returns the root directory for temporary directories.
GetTempDirRootDir() string
// Get returns the mountpoint for the layered filesystem referred
// to by this id. You can optionally specify a mountLabel or "".
// Optionally it gets the mappings used to create the layer.
Expand Down
34 changes: 30 additions & 4 deletions drivers/overlay/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/containers/storage/drivers/quota"
"github.com/containers/storage/internal/dedup"
"github.com/containers/storage/internal/staging_lockfile"
"github.com/containers/storage/internal/tempdir"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/directory"
Expand Down Expand Up @@ -1305,17 +1306,24 @@ func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMa

// Remove cleans the directories that are created for this id.
func (d *Driver) Remove(id string) error {
return d.removeCommon(id, func(path string) error {
return system.EnsureRemoveAll(path)
})
}

func (d *Driver) removeCommon(id string, cleanup func(string) error) error {
dir := d.dir(id)
lid, err := os.ReadFile(path.Join(dir, "link"))
if err == nil {
if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil {
linkPath := path.Join(d.home, linkDir, string(lid))
if err := cleanup(linkPath); err != nil {
logrus.Debugf("Failed to remove link: %v", err)
}
}

d.releaseAdditionalLayerByID(id)

if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) {
if err := cleanup(dir); err != nil && !os.IsNotExist(err) {
return err
}
if d.quotaCtl != nil {
Expand All @@ -1327,6 +1335,24 @@ func (d *Driver) Remove(id string) error {
return nil
}

func (d *Driver) GetTempDirRootDir() string {
return filepath.Join(d.home, stagingDir)
}

func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
t, err := tempdir.NewTempDir(d.GetTempDirRootDir())
if err != nil {
return nil, err
}

if err := d.removeCommon(id, func(path string) error {
return t.Add(path)
}); err != nil {
return t.Cleanup, fmt.Errorf("failed to add to stage directory: %w", err)
}
return t.Cleanup, nil
}

// recreateSymlinks goes through the driver's home directory and checks if the diff directory
// under each layer has a symlink created for it under the linkDir. If the symlink does not
// exist, it creates them
Expand All @@ -1353,8 +1379,8 @@ func (d *Driver) recreateSymlinks() error {
// Check that for each layer, there's a link in "l" with the name in
// the layer's "link" file that points to the layer's "diff" directory.
for _, dir := range dirs {
// Skip over the linkDir and anything that is not a directory
if dir.Name() == linkDir || !dir.IsDir() {
// Skip over the linkDir and anything that is not a directory or tempDir
if dir.Name() == linkDir || !dir.IsDir() || dir.Name() == stagingDir {
continue
}
// Read the "link" file under each layer to get the name of the symlink
Expand Down
16 changes: 16 additions & 0 deletions drivers/vfs/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/internal/dedup"
"github.com/containers/storage/internal/tempdir"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/fileutils"
Expand Down Expand Up @@ -244,6 +245,21 @@ func (d *Driver) Remove(id string) error {
return system.EnsureRemoveAll(d.dir(id))
}

func (d *Driver) GetTempDirRootDir() string {
return filepath.Join(d.home, "tempdirs")
}

func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
t, err := tempdir.NewTempDir(d.GetTempDirRootDir())
if err != nil {
return nil, err
}
if err := t.Add(d.dir(id)); err != nil {
return nil, err
}
return t.Cleanup, nil
}

// Get returns the directory for the given id.
func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) {
dir := d.dir(id)
Expand Down
12 changes: 12 additions & 0 deletions drivers/windows/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/Microsoft/go-winio/backuptar"
"github.com/Microsoft/hcsshim"
graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/internal/tempdir"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/fileutils"
Expand Down Expand Up @@ -1014,3 +1015,14 @@ func parseStorageOpt(storageOpt map[string]string) (*storageOptions, error) {
}
return &options, nil
}

// DeferredRemove is not implemented.
// It calls Remove directly.
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
return nil, d.Remove(id)
}

// GetTempDirRootDir is not implemented.
func (d *Driver) GetTempDirRootDir() string {
return ""
}
12 changes: 12 additions & 0 deletions drivers/zfs/zfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/internal/tempdir"
"github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
Expand Down Expand Up @@ -406,6 +407,12 @@ func (d *Driver) Remove(id string) error {
return nil
}

// DeferredRemove is not implemented.
// It calls Remove directly.
func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) {
return nil, d.Remove(id)
}

// Get returns the mountpoint for the given id after creating the target directories if necessary.
func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) {
mountpoint := d.mountPath(id)
Expand Down Expand Up @@ -516,3 +523,8 @@ func (d *Driver) AdditionalImageStores() []string {
func (d *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
return graphdriver.DedupResult{}, nil
}

// GetTempDirRootDir is not implemented.
func (d *Driver) GetTempDirRootDir() string {
return ""
}
Loading