summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/sentry/fs/overlay.go22
-rw-r--r--runsc/boot/fs.go16
2 files changed, 31 insertions, 7 deletions
diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go
index 40eed3feb..90d21642e 100644
--- a/pkg/sentry/fs/overlay.go
+++ b/pkg/sentry/fs/overlay.go
@@ -103,6 +103,28 @@ func NewOverlayRoot(ctx context.Context, upper *Inode, lower *Inode, flags Mount
return newOverlayInode(ctx, overlay, msrc), nil
}
+// NewOverlayRootFile produces the root of an overlay that points to a file.
+//
+// Preconditions:
+//
+// - lower must be non-nil.
+// - lower should not expose character devices, pipes, or sockets, because
+// copying up these types of files is not supported. Neither it can be a dir.
+// - lower must not require that file objects be revalidated.
+// - lower must not have dynamic file/directory content.
+func NewOverlayRootFile(ctx context.Context, upperMS *MountSource, lower *Inode, flags MountSourceFlags) (*Inode, error) {
+ if IsRegular(lower.StableAttr) {
+ return nil, fmt.Errorf("lower Inode is not a regular file")
+ }
+ msrc := newOverlayMountSource(upperMS, lower.MountSource, flags)
+ overlay, err := newOverlayEntry(ctx, nil, lower, true)
+ if err != nil {
+ msrc.DecRef()
+ return nil, err
+ }
+ return newOverlayInode(ctx, overlay, msrc), nil
+}
+
// newOverlayInode creates a new Inode for an overlay.
func newOverlayInode(ctx context.Context, o *overlayEntry, msrc *MountSource) *Inode {
var inode *Inode
diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go
index 7243153f2..3113f1857 100644
--- a/runsc/boot/fs.go
+++ b/runsc/boot/fs.go
@@ -16,7 +16,6 @@ package boot
import (
"fmt"
- "os"
"path/filepath"
"strings"
@@ -209,6 +208,13 @@ func addOverlay(ctx context.Context, conf *Config, lower *fs.Inode, name string,
lowerFlags.ReadOnly = false
tmpFS := mustFindFilesystem("tmpfs")
+ if !fs.IsDir(lower.StableAttr) {
+ // Create overlay on top of mount file, e.g. /etc/hostname.
+ msrc := fs.NewCachingMountSource(tmpFS, lowerFlags)
+ return fs.NewOverlayRootFile(ctx, msrc, lower, lowerFlags)
+ }
+
+ // Create overlay on top of mount dir.
upper, err := tmpFS.Mount(ctx, name+"-upper", lowerFlags, "")
if err != nil {
return nil, fmt.Errorf("failed to create tmpfs overlay: %v", err)
@@ -248,13 +254,9 @@ func mountSubmount(ctx context.Context, spec *specs.Spec, conf *Config, mns *fs.
default:
return fmt.Errorf("invalid file access type: %v", conf.FileAccess)
}
+ // If configured, add overlay to all writable mounts.
+ useOverlay = conf.Overlay && !mountFlags(m.Options).ReadOnly
- fi, err := os.Stat(m.Source)
- if err != nil {
- return err
- }
- // Add overlay to all writable mounts, except when mapping an individual file.
- useOverlay = conf.Overlay && !mountFlags(m.Options).ReadOnly && fi.Mode().IsDir()
default:
// TODO: Support all the mount types and make this a
// fatal error. Most applications will "just work" without