summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/proc/mounts.go
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2019-05-23 04:15:18 -0700
committerShentubot <shentubot@google.com>2019-05-23 04:16:10 -0700
commit9006304dfecf3670ad03c9629f9a4ac3273c386a (patch)
tree958b4c09c1118cd173675618002a2c1f32384071 /pkg/sentry/fs/proc/mounts.go
parent022bd0fd1091a29a41fa4c065ac35e45e3d6c576 (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/mounts.go')
-rw-r--r--pkg/sentry/fs/proc/mounts.go48
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