diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-08-20 23:31:26 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-08-20 23:31:26 +0000 |
commit | 978e1e28175603d73d9cda7800d1046fa51a79f6 (patch) | |
tree | f0c2be7c248f360485d2c17e9199cbe7a13bd409 /pkg/sentry | |
parent | 3409e128c96d6a58e72c3abc9d37413cb6e0b7cb (diff) | |
parent | 73c69cb4d8e7f47ce9205844e5f6e369ff4dfa53 (diff) |
Merge release-20200810.0-78-g73c69cb4d (automated)
Diffstat (limited to 'pkg/sentry')
-rw-r--r-- | pkg/sentry/vfs/vfs.go | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/pkg/sentry/vfs/vfs.go b/pkg/sentry/vfs/vfs.go index 8a79e1325..ec27562d6 100644 --- a/pkg/sentry/vfs/vfs.go +++ b/pkg/sentry/vfs/vfs.go @@ -36,6 +36,7 @@ package vfs import ( "fmt" + "path" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" @@ -782,6 +783,38 @@ func (vfs *VirtualFilesystem) SyncAllFilesystems(ctx context.Context) error { return retErr } +// MkdirAllAt recursively creates non-existent directories on the given path +// (including the last component). +func (vfs *VirtualFilesystem) MkdirAllAt(ctx context.Context, currentPath string, root VirtualDentry, creds *auth.Credentials, mkdirOpts *MkdirOptions) error { + pop := &PathOperation{ + Root: root, + Start: root, + Path: fspath.Parse(currentPath), + } + stat, err := vfs.StatAt(ctx, creds, pop, &StatOptions{Mask: linux.STATX_TYPE}) + switch err { + case nil: + if stat.Mask&linux.STATX_TYPE == 0 || stat.Mode&linux.FileTypeMask != linux.ModeDirectory { + return syserror.ENOTDIR + } + // Directory already exists. + return nil + case syserror.ENOENT: + // Expected, we will create the dir. + default: + return fmt.Errorf("stat failed for %q during directory creation: %w", currentPath, err) + } + + // Recurse to ensure parent is created and then create the final directory. + if err := vfs.MkdirAllAt(ctx, path.Dir(currentPath), root, creds, mkdirOpts); err != nil { + return err + } + if err := vfs.MkdirAt(ctx, creds, pop, mkdirOpts); err != nil { + return fmt.Errorf("failed to create directory %q: %w", currentPath, err) + } + return nil +} + // A VirtualDentry represents a node in a VFS tree, by combining a Dentry // (which represents a node in a Filesystem's tree) and a Mount (which // represents the Filesystem's position in a VFS mount tree). |