diff options
-rw-r--r-- | pkg/sentry/fs/overlay.go | 22 | ||||
-rw-r--r-- | runsc/boot/fs.go | 16 |
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 |