summaryrefslogtreecommitdiffhomepage
path: root/runsc/boot/fs.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-07-03 10:35:27 -0700
committerShentubot <shentubot@google.com>2018-07-03 10:36:22 -0700
commit4500155ffc5edfc2d417297d3367f5656dbea5a7 (patch)
treee96250e876f7a8022ee4169a87f20860f4a718a1 /runsc/boot/fs.go
parent614475196201a380d969ed269d99a8ad70ca1885 (diff)
runsc: Mount "mandatory" mounts right after mounting the root.
The /proc and /sys mounts are "mandatory" in the sense that they should be mounted in the sandbox even when they are not included in the spec. Runsc treats /tmp similarly, because it is faster to use the internal tmpfs implementation instead of proxying to the host. However, the spec may contain submounts of these mandatory mounts (particularly for /tmp). In those cases, we must mount our mandatory mounts before the submount, otherwise the submount will be masked. Since the mandatory mounts are all top-level directories, we can mount them right after the root. PiperOrigin-RevId: 203145635 Change-Id: Id69bae771d32c1a5b67e08c8131b73d9b42b2fbf
Diffstat (limited to 'runsc/boot/fs.go')
-rw-r--r--runsc/boot/fs.go22
1 files changed, 16 insertions, 6 deletions
diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go
index a9b2f225a..f36bcdc2e 100644
--- a/runsc/boot/fs.go
+++ b/runsc/boot/fs.go
@@ -83,7 +83,7 @@ func createMountNamespace(userCtx context.Context, rootCtx context.Context, spec
}
// compileMounts returns the supported mounts from the mount spec, adding any
-// additional mounts that are required by the OCI specification.
+// mandatory mounts that are required by the OCI specification.
func compileMounts(spec *specs.Spec) []specs.Mount {
// Keep track of whether proc, sys, and tmp were mounted.
var procMounted, sysMounted, tmpMounted bool
@@ -119,14 +119,15 @@ func compileMounts(spec *specs.Spec) []specs.Mount {
// Mount proc and sys even if the user did not ask for it, as the spec
// says we SHOULD.
+ var mandatoryMounts []specs.Mount
if !procMounted {
- mounts = append(mounts, specs.Mount{
+ mandatoryMounts = append(mandatoryMounts, specs.Mount{
Type: "proc",
Destination: "/proc",
})
}
if !sysMounted {
- mounts = append(mounts, specs.Mount{
+ mandatoryMounts = append(mandatoryMounts, specs.Mount{
Type: "sysfs",
Destination: "/sys",
})
@@ -136,11 +137,20 @@ func compileMounts(spec *specs.Spec) []specs.Mount {
// rely on the host /tmp, but this is a nice optimization, and fixes
// some apps that call mknod in /tmp.
if !tmpMounted {
- mounts = append(mounts, specs.Mount{
+ // TODO: If the host /tmp (or a mount at /tmp) has
+ // files in it, we should overlay our tmpfs implementation over
+ // that. Until then, the /tmp mount will always appear empty at
+ // container creation.
+ mandatoryMounts = append(mandatoryMounts, specs.Mount{
Type: "tmpfs",
Destination: "/tmp",
})
}
+
+ // The mandatory mounts should be ordered right after the root, in case
+ // there are submounts of these mandatory mounts already in the spec.
+ mounts = append(mounts[:0], append(mandatoryMounts, mounts[0:]...)...)
+
return mounts
}
@@ -430,8 +440,8 @@ func addRestoreMount(conf *Config, renv *fs.RestoreEnvironment, m specs.Mount, f
if err != nil {
return err
}
- // TODO: Fix this when we support all the mount types and make this a
- // fatal error.
+ // TODO: Fix this when we support all the mount types and
+ // make this a fatal error.
if fsName == "" {
return nil
}