diff --git a/hst/fs.go b/hst/fs.go index 92ca51af..13645d1a 100644 --- a/hst/fs.go +++ b/hst/fs.go @@ -56,8 +56,10 @@ type Ops interface { // ApplyState holds the address of [Ops] and any relevant application state. type ApplyState struct { - // AutoEtcPrefix is the prefix for [FSBind] in autoetc [FSBind.Special] condition. + // Prefix for [FSBind] in autoetc [FSBind.Special] condition. AutoEtcPrefix string + // Whether to skip remounting root. + NoRemountRoot bool Ops } diff --git a/hst/fsoverlay.go b/hst/fsoverlay.go index 738ecf53..b06c1e7e 100644 --- a/hst/fsoverlay.go +++ b/hst/fsoverlay.go @@ -5,6 +5,7 @@ import ( "strings" "hakurei.app/check" + "hakurei.app/fhs" ) func init() { gob.Register(new(FSOverlay)) } @@ -69,9 +70,12 @@ func (o *FSOverlay) Apply(z *ApplyState) { return } - if o.Upper != nil && o.Work != nil { // rw + if o.Upper != nil && o.Work != nil { z.Overlay(o.Target, o.Upper, o.Work, o.Lower...) - } else { // ro + if o.Target.Is(fhs.AbsRoot) { + z.NoRemountRoot = true + } + } else { z.OverlayReadonly(o.Target, o.Lower...) } } diff --git a/hst/fsoverlay_test.go b/hst/fsoverlay_test.go index f1097481..1b14e7c9 100644 --- a/hst/fsoverlay_test.go +++ b/hst/fsoverlay_test.go @@ -49,5 +49,18 @@ func TestFSOverlay(t *testing.T) { Lower: ms("/tmp/.src0", "/tmp/.src1"), }}, m("/mnt/src"), ms("/tmp/.src0", "/tmp/.src1"), "*/mnt/src:/tmp/.src0:/tmp/.src1"}, + + {"no remount root", &hst.FSOverlay{ + Target: m("/"), + Lower: ms("/tmp/.src0", "/tmp/.src1"), + Upper: m("/tmp/upper"), + Work: m("/tmp/work"), + }, true, container.Ops{&container.MountOverlayOp{ + Target: m("/"), + Lower: ms("/tmp/.src0", "/tmp/.src1"), + Upper: m("/tmp/upper"), + Work: m("/tmp/work"), + }}, m("/"), ms("/tmp/upper", "/tmp/work", "/tmp/.src0", "/tmp/.src1"), + "w*/:/tmp/upper:/tmp/work:/tmp/.src0:/tmp/.src1"}, }) } diff --git a/internal/outcome/spcontainer.go b/internal/outcome/spcontainer.go index 0ad1de50..d9398d2c 100644 --- a/internal/outcome/spcontainer.go +++ b/internal/outcome/spcontainer.go @@ -290,7 +290,9 @@ func (s *spFilesystemOp) toContainer(state *outcomeStateParams) error { if state.Container.Flags&hst.FDevice == 0 { state.params.Remount(fhs.AbsDev, syscall.MS_RDONLY) } - state.params.Remount(fhs.AbsRoot, syscall.MS_RDONLY) + if !state.as.NoRemountRoot { + state.params.Remount(fhs.AbsRoot, syscall.MS_RDONLY) + } state.params.Env = make([]string, 0, len(state.env)) for key, value := range state.env {