diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-09-11 23:13:20 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-09-11 23:13:20 +0000 |
commit | 2c7d03d2378865ee92d7ae24e48748f17233e783 (patch) | |
tree | f84e553a41525dd9dc4dc64f6b6fb1bbdf1481a8 /pkg/sentry/vfs/vfs.go | |
parent | 51194daa8da2bee362c9ecb6491016038e5f8436 (diff) | |
parent | 1f4fb817c8ff8be7239a99baff01d8f20b2e9abd (diff) |
Merge release-20200907.0-36-g1f4fb817c (automated)
Diffstat (limited to 'pkg/sentry/vfs/vfs.go')
-rw-r--r-- | pkg/sentry/vfs/vfs.go | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/pkg/sentry/vfs/vfs.go b/pkg/sentry/vfs/vfs.go index ed1cf99ba..1ebf355ef 100644 --- a/pkg/sentry/vfs/vfs.go +++ b/pkg/sentry/vfs/vfs.go @@ -819,6 +819,30 @@ func (vfs *VirtualFilesystem) MkdirAllAt(ctx context.Context, currentPath string return nil } +// MakeSyntheticMountpoint creates parent directories of target if they do not +// exist and attempts to create a directory for the mountpoint. If a +// non-directory file already exists there then we allow it. +func (vfs *VirtualFilesystem) MakeSyntheticMountpoint(ctx context.Context, target string, root VirtualDentry, creds *auth.Credentials) error { + mkdirOpts := &MkdirOptions{Mode: 0777, ForSyntheticMountpoint: true} + + // Make sure the parent directory of target exists. + if err := vfs.MkdirAllAt(ctx, path.Dir(target), root, creds, mkdirOpts); err != nil { + return fmt.Errorf("failed to create parent directory of mountpoint %q: %w", target, err) + } + + // Attempt to mkdir the final component. If a file (of any type) exists + // then we let allow mounting on top of that because we do not require the + // target to be an existing directory, unlike Linux mount(2). + if err := vfs.MkdirAt(ctx, creds, &PathOperation{ + Root: root, + Start: root, + Path: fspath.Parse(target), + }, mkdirOpts); err != nil && err != syserror.EEXIST { + return fmt.Errorf("failed to create mountpoint %q: %w", target, 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). |