runsc: All non-root bind mounts should be shared.

This CL changes the semantics of the "--file-access" flag so that it only
affects the root filesystem.  The default remains "exclusive" which is the
common use case, as neither Docker nor K8s supports sharing the root.

Keeping the root fs as "exclusive" means that the fs-intensive work done during
application startup will mostly be cacheable, and thus faster.

Non-root bind mounts will always be shared.

This CL also removes some redundant FSAccessType validations.  We validate this
flag in main(), so we can assume it is valid afterwards.

PiperOrigin-RevId: 214359936
Change-Id: I7e75d7bf52dbd7fa834d0aacd4034868314f3b51
This commit is contained in:
Nicolas Lacasse 2018-09-24 17:21:16 -07:00 committed by Shentubot
parent 4094480b28
commit d489336784
2 changed files with 15 additions and 25 deletions

View File

@ -204,19 +204,13 @@ func createRootMount(ctx context.Context, spec *specs.Spec, conf *Config, fds *f
err error
)
switch conf.FileAccess {
case FileAccessShared, FileAccessExclusive:
fd := fds.remove()
log.Infof("Mounting root over 9P, ioFD: %d", fd)
hostFS := mustFindFilesystem("9p")
opts := p9MountOptions(conf, fd)
rootInode, err = hostFS.Mount(ctx, rootDevice, mf, strings.Join(opts, ","))
if err != nil {
return nil, fmt.Errorf("failed to generate root mount point: %v", err)
}
default:
return nil, fmt.Errorf("invalid file access type: %v", conf.FileAccess)
fd := fds.remove()
log.Infof("Mounting root over 9P, ioFD: %d", fd)
hostFS := mustFindFilesystem("9p")
opts := p9MountOptions(fd, conf.FileAccess)
rootInode, err = hostFS.Mount(ctx, rootDevice, mf, strings.Join(opts, ","))
if err != nil {
return nil, fmt.Errorf("failed to generate root mount point: %v", err)
}
// We need to overlay the root on top of a ramfs with stub directories
@ -282,14 +276,10 @@ func getMountNameAndOptions(conf *Config, m specs.Mount, fds *fdDispenser) (stri
opts, err = parseAndFilterOptions(m.Options, "mode", "uid", "gid")
case bind:
switch conf.FileAccess {
case FileAccessShared, FileAccessExclusive:
fd := fds.remove()
fsName = "9p"
opts = p9MountOptions(conf, fd)
default:
err = fmt.Errorf("invalid file access type: %v", conf.FileAccess)
}
fd := fds.remove()
fsName = "9p"
// Non-root bind mounts are always shared.
opts = p9MountOptions(fd, FileAccessShared)
// If configured, add overlay to all writable mounts.
useOverlay = conf.Overlay && !mountFlags(m.Options).ReadOnly
@ -407,14 +397,14 @@ func mkdirAll(ctx context.Context, mns *fs.MountNamespace, path string) error {
}
// p9MountOptions creates a slice of options for a p9 mount.
func p9MountOptions(conf *Config, fd int) []string {
func p9MountOptions(fd int, fa FileAccessType) []string {
opts := []string{
"trans=fd",
"rfdno=" + strconv.Itoa(fd),
"wfdno=" + strconv.Itoa(fd),
"privateunixsocket=true",
}
if conf.FileAccess == FileAccessShared {
if fa == FileAccessShared {
opts = append(opts, "cache=remote_revalidating")
}
return opts
@ -500,7 +490,7 @@ func createRestoreEnvironment(spec *specs.Spec, conf *Config, fds *fdDispenser)
// Add root mount.
fd := fds.remove()
opts := p9MountOptions(conf, fd)
opts := p9MountOptions(fd, conf.FileAccess)
mf := fs.MountSourceFlags{}
if spec.Root.Readonly {

View File

@ -58,7 +58,7 @@ var (
// Flags that control sandbox runtime behavior.
platform = flag.String("platform", "ptrace", "specifies which platform to use: ptrace (default), kvm")
network = flag.String("network", "sandbox", "specifies which network to use: sandbox (default), host, none. Using network inside the sandbox is more secure because it's isolated from the host network.")
fileAccess = flag.String("file-access", "exclusive", "specifies which filesystem to use: exclusive (default), shared. Setting 'shared' will disable caches and should be used if external modifications to the filesystem are expected.")
fileAccess = flag.String("file-access", "exclusive", "specifies which filesystem to use for the root mount: exclusive (default), shared. Volume mounts are always shared.")
overlay = flag.Bool("overlay", false, "wrap filesystem mounts with writable overlay. All modifications are stored in memory inside the sandbox.")
multiContainer = flag.Bool("multi-container", false, "enable *experimental* multi-container support.")
watchdogAction = flag.String("watchdog-action", "log", "sets what action the watchdog takes when triggered: log (default), panic.")