Skip to content

Commit 24f71da

Browse files
committed
Handle mounts on top of sysbox-fs emualated paths.
This enables mounting of binfmt_misc at /proc/sys/fs/binfmt_misc inside Sysbox containers. Signed-off-by: Cesar Talledo <[email protected]>
1 parent d075d71 commit 24f71da

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

libcontainer/rootfs_linux.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/opencontainers/runc/libcontainer/devices"
3232
"github.com/opencontainers/runc/libcontainer/system"
3333
"github.com/opencontainers/runc/libcontainer/utils"
34+
"github.com/opencontainers/runc/libsysbox/syscont"
3435
"github.com/opencontainers/runtime-spec/specs-go"
3536
"github.com/opencontainers/selinux/go-selinux/label"
3637
"github.com/sirupsen/logrus"
@@ -66,7 +67,7 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
6667
return newSystemErrorWithCause(err, "effecting rootfs mount")
6768
}
6869

69-
if err := doMounts(config, pipe); err != nil {
70+
if err := doMounts(config, pipe, false); err != nil {
7071
return newSystemErrorWithCause(err, "setting up rootfs mounts")
7172
}
7273

@@ -219,6 +220,7 @@ func prepareBindDest(m *configs.Mount, absDestPath bool, config *configs.Config,
219220

220221
// update the mount with the correct dest after symlinks are resolved.
221222
m.Destination = dest
223+
222224
if err = createIfNotExists(dest, m.BindSrcInfo.IsDir, config, pipe); err != nil {
223225
return err
224226
}
@@ -501,7 +503,7 @@ func mountToRootfs(m *configs.Mount, config *configs.Config, enableCgroupns bool
501503
}
502504
}
503505

504-
func doBindMounts(config *configs.Config, pipe io.ReadWriter) error {
506+
func doBindMounts(config *configs.Config, pipe io.ReadWriter, doSysboxfsOvermountsOnly bool) error {
505507

506508
// sysbox-runc: the sys container's init process is in a dedicated
507509
// user-ns, so it may not have search permission to the bind mount
@@ -527,6 +529,12 @@ func doBindMounts(config *configs.Config, pipe io.ReadWriter) error {
527529
continue
528530
}
529531

532+
isSysboxfsOvermount := isSysboxfsOvermount(m)
533+
if doSysboxfsOvermountsOnly && !isSysboxfsOvermount ||
534+
!doSysboxfsOvermountsOnly && isSysboxfsOvermount {
535+
continue
536+
}
537+
530538
// Determine if the current mount is dependent on a prior one.
531539
mntDependsOnPrior := false
532540
for _, mr := range mntReqs {
@@ -584,6 +592,17 @@ func doBindMounts(config *configs.Config, pipe io.ReadWriter) error {
584592
return nil
585593
}
586594

595+
// isSysboxfsOvermount returns true if the given mount destination is under a
596+
// sysbox-fs managed mountpoint.
597+
func isSysboxfsOvermount(m *configs.Mount) bool {
598+
for _, sysboxfsMount := range syscont.SysboxfsMounts {
599+
if strings.HasPrefix(m.Destination, sysboxfsMount.Destination+"/") {
600+
return true
601+
}
602+
}
603+
return false
604+
}
605+
587606
func chownMounts(config *configs.Config, pipe io.ReadWriter, chownList []string) error {
588607
chownReqs := []opReq{}
589608

@@ -985,6 +1004,7 @@ func chroot() error {
9851004

9861005
// createIfNotExists creates a file or a directory only if it does not already exist.
9871006
func createIfNotExists(path string, isDir bool, config *configs.Config, pipe io.ReadWriter) error {
1007+
9881008
if _, err := os.Stat(path); err != nil {
9891009
if os.IsNotExist(err) {
9901010
if isDir {
@@ -1179,13 +1199,22 @@ func doRootfsIDMapping(config *configs.Config, pipe io.ReadWriter) error {
11791199
return nil
11801200
}
11811201

1182-
// sysbox-runc: doMounts sets up all of the container's mounts as specified in the given config.
1183-
func doMounts(config *configs.Config, pipe io.ReadWriter) error {
1202+
// sysbox-runc: doMounts sets up the container's mounts as specified in the given config.
1203+
// If sysboxfsOvermounts is true, then only mounts on top of sysbox-fs emulated paths are
1204+
// mounted (e.g., mounts under /proc/sys/). Otherwise such mounts are skipped.
1205+
func doMounts(config *configs.Config, pipe io.ReadWriter, doSysboxfsOvermountsOnly bool) error {
11841206

11851207
chownList := []string{}
11861208

11871209
// Do non-bind mounts
11881210
for _, m := range config.Mounts {
1211+
1212+
isSysboxfsOvermount := isSysboxfsOvermount(m)
1213+
if doSysboxfsOvermountsOnly && !isSysboxfsOvermount ||
1214+
!doSysboxfsOvermountsOnly && isSysboxfsOvermount {
1215+
continue
1216+
}
1217+
11891218
if m.Device != "bind" {
11901219
if err := mountToRootfs(m, config, true, pipe); err != nil {
11911220
return newSystemErrorWithCausef(err, "mounting %q to rootfs %q at %q", m.Source, config.Rootfs, m.Destination)
@@ -1207,7 +1236,7 @@ func doMounts(config *configs.Config, pipe io.ReadWriter) error {
12071236
}
12081237
}
12091238

1210-
if err := doBindMounts(config, pipe); err != nil {
1239+
if err := doBindMounts(config, pipe, doSysboxfsOvermountsOnly); err != nil {
12111240
return err
12121241
}
12131242

libcontainer/standard_init_linux.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func (l *linuxStandardInit) Init() error {
9696

9797
// initialises the labeling system
9898
selinux.GetEnabled()
99+
99100
if err := prepareRootfs(l.pipe, l.config); err != nil {
100101
return err
101102
}
@@ -195,6 +196,13 @@ func (l *linuxStandardInit) Init() error {
195196
}
196197
}
197198

199+
// Do mounts on top of sysbox-fs emulated paths (e.g., mount binfmt_misc on
200+
// /proc/sys/fs/binfmt_misc). This has to be done after we've registered with
201+
// sysbox-fs since the mountpoint is under a sysbox-fs emulated path.
202+
if err := doMounts(l.config.Config, l.pipe, true); err != nil {
203+
return errors.Wrap(err, "doing mounts on top of sysbox-fs")
204+
}
205+
198206
// Handle masked paths
199207
for _, path := range l.config.Config.MaskPaths {
200208
if err := maskPath(path, l.config.Config.MountLabel); err != nil {

0 commit comments

Comments
 (0)