diff options
author | Fabricio Voznika <fvoznika@google.com> | 2019-05-23 04:15:18 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-05-23 04:16:10 -0700 |
commit | 9006304dfecf3670ad03c9629f9a4ac3273c386a (patch) | |
tree | 958b4c09c1118cd173675618002a2c1f32384071 /pkg/sentry/fs/proc | |
parent | 022bd0fd1091a29a41fa4c065ac35e45e3d6c576 (diff) |
Initial support for bind mounts
Separate MountSource from Mount. This is needed to allow
mounts to be shared by multiple containers within the same
pod.
PiperOrigin-RevId: 249617810
Change-Id: Id2944feb7e4194951f355cbe6d4944ae3c02e468
Diffstat (limited to 'pkg/sentry/fs/proc')
-rw-r--r-- | pkg/sentry/fs/proc/mounts.go | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index b5e01301f..1f7817947 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -27,7 +27,7 @@ import ( // forEachMountSource runs f for the process root mount and each mount that is a // descendant of the root. -func forEachMountSource(t *kernel.Task, fn func(string, *fs.MountSource)) { +func forEachMount(t *kernel.Task, fn func(string, *fs.Mount)) { var fsctx *kernel.FSContext t.WithMuLocked(func(t *kernel.Task) { fsctx = t.FSContext() @@ -46,16 +46,14 @@ func forEachMountSource(t *kernel.Task, fn func(string, *fs.MountSource)) { } defer rootDir.DecRef() - if rootDir.Inode == nil { - panic(fmt.Sprintf("root dirent has nil inode: %+v", rootDir)) - } - if rootDir.Inode.MountSource == nil { - panic(fmt.Sprintf("root dirent has nil mount: %+v", rootDir)) + mnt := t.MountNamespace().FindMount(rootDir) + if mnt == nil { + // Has it just been unmounted? + return } - - ms := append(rootDir.Inode.MountSource.Submounts(), rootDir.Inode.MountSource) + ms := t.MountNamespace().AllMountsUnder(mnt) sort.Slice(ms, func(i, j int) bool { - return ms[i].ID() < ms[j].ID() + return ms[i].ID < ms[j].ID }) for _, m := range ms { mroot := m.Root() @@ -89,26 +87,27 @@ func (mif *mountInfoFile) ReadSeqFileData(ctx context.Context, handle seqfile.Se } var buf bytes.Buffer - forEachMountSource(mif.t, func(mountPath string, m *fs.MountSource) { + forEachMount(mif.t, func(mountPath string, m *fs.Mount) { // Format: // 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue // (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11) // (1) MountSource ID. - fmt.Fprintf(&buf, "%d ", m.ID()) + fmt.Fprintf(&buf, "%d ", m.ID) // (2) Parent ID (or this ID if there is no parent). - pID := m.ID() - if p := m.Parent(); p != nil { - pID = p.ID() + pID := m.ID + if !m.IsRoot() && !m.IsUndo() { + pID = m.ParentID } fmt.Fprintf(&buf, "%d ", pID) // (3) Major:Minor device ID. We don't have a superblock, so we // just use the root inode device number. mroot := m.Root() + defer mroot.DecRef() + sa := mroot.Inode.StableAttr - mroot.DecRef() fmt.Fprintf(&buf, "%d:%d ", sa.DeviceFileMajor, sa.DeviceFileMinor) // (4) Root: the pathname of the directory in the filesystem @@ -122,14 +121,15 @@ func (mif *mountInfoFile) ReadSeqFileData(ctx context.Context, handle seqfile.Se fmt.Fprintf(&buf, "%s ", mountPath) // (6) Mount options. + flags := mroot.Inode.MountSource.Flags opts := "rw" - if m.Flags.ReadOnly { + if flags.ReadOnly { opts = "ro" } - if m.Flags.NoAtime { + if flags.NoAtime { opts += ",noatime" } - if m.Flags.NoExec { + if flags.NoExec { opts += ",noexec" } fmt.Fprintf(&buf, "%s ", opts) @@ -139,7 +139,7 @@ func (mif *mountInfoFile) ReadSeqFileData(ctx context.Context, handle seqfile.Se fmt.Fprintf(&buf, "- ") // (9) Filesystem type. - fmt.Fprintf(&buf, "%s ", m.FilesystemType) + fmt.Fprintf(&buf, "%s ", mroot.Inode.MountSource.FilesystemType) // (10) Mount source: filesystem-specific information or "none". fmt.Fprintf(&buf, "none ") @@ -171,7 +171,7 @@ func (mf *mountsFile) ReadSeqFileData(ctx context.Context, handle seqfile.SeqHan } var buf bytes.Buffer - forEachMountSource(mf.t, func(mountPath string, m *fs.MountSource) { + forEachMount(mf.t, func(mountPath string, m *fs.Mount) { // Format: // <special device or remote filesystem> <mount point> <filesystem type> <mount options> <needs dump> <fsck order> // @@ -182,11 +182,15 @@ func (mf *mountsFile) ReadSeqFileData(ctx context.Context, handle seqfile.SeqHan // Only ro/rw option is supported for now. // // The "needs dump"and fsck flags are always 0, which is allowed. + root := m.Root() + defer root.DecRef() + + flags := root.Inode.MountSource.Flags opts := "rw" - if m.Flags.ReadOnly { + if flags.ReadOnly { opts = "ro" } - fmt.Fprintf(&buf, "%s %s %s %s %d %d\n", "none", mountPath, m.FilesystemType, opts, 0, 0) + fmt.Fprintf(&buf, "%s %s %s %s %d %d\n", "none", mountPath, root.Inode.MountSource.FilesystemType, opts, 0, 0) }) return []seqfile.SeqData{{Buf: buf.Bytes(), Handle: (*mountsFile)(nil)}}, 0 |