Skip to content

Commit b1187e9

Browse files
Fallback for mount_setattr
This is not based on kernel version, just to check syscall existence. Signed-off-by: Alexey Perevalov <[email protected]>
1 parent 609781c commit b1187e9

File tree

1 file changed

+52
-12
lines changed

1 file changed

+52
-12
lines changed

libcontainer/rootfs_linux.go

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"path/filepath"
1111
"strconv"
1212
"strings"
13+
"sync"
1314
"syscall"
1415
"time"
1516

@@ -331,6 +332,53 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
331332
})
332333
}
333334

335+
var (
336+
syscallOnce sync.Once
337+
syscallErr error
338+
)
339+
340+
func mountByMove(m *configs.Mount, dest string) error {
341+
// Check once for all mount point that syscall exists
342+
syscallOnce.Do(func() {
343+
_, err := unix.OpenTree(-int(unix.EBADF), "", uint(unix.OPEN_TREE_CLONE|unix.OPEN_TREE_CLOEXEC|unix.AT_EMPTY_PATH|unix.AT_RECURSIVE))
344+
if err == unix.ENOSYS {
345+
logrus.Warnf("no open_tree syscall on the system")
346+
syscallErr = err
347+
}
348+
349+
err = unix.MoveMount(-int(unix.EBADF), "", unix.AT_FDCWD, "", unix.MOVE_MOUNT_F_EMPTY_PATH)
350+
if err == unix.ENOSYS {
351+
logrus.Warnf("no move_mount syscall on the system")
352+
syscallErr = err
353+
}
354+
355+
err = unix.MountSetattr(-int(unix.EBADF), "", unix.AT_EMPTY_PATH|unix.AT_RECURSIVE, nil)
356+
if err == unix.ENOSYS {
357+
logrus.Warnf("no mount_setattr syscall on the system")
358+
syscallErr = err
359+
}
360+
})
361+
if syscallErr != nil {
362+
return syscallErr
363+
}
364+
// If syscalls exist we may fail somewhere else
365+
treeFd, err := unix.OpenTree(-int(unix.EBADF), m.Source, uint(unix.OPEN_TREE_CLONE|unix.OPEN_TREE_CLOEXEC|unix.AT_EMPTY_PATH|unix.AT_RECURSIVE))
366+
if err != nil || treeFd < 0 {
367+
return err
368+
}
369+
370+
err = unix.MoveMount(treeFd, "", unix.AT_FDCWD, dest, unix.MOVE_MOUNT_F_EMPTY_PATH)
371+
if err != nil {
372+
return err
373+
}
374+
375+
if err := mountIDMapMapped(m, treeFd); err != nil {
376+
return err
377+
}
378+
logrus.Debugf("move_mount succeed")
379+
return nil
380+
}
381+
334382
func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
335383
// Set up a scratch dir for the tmpfs on the host.
336384
tmpdir, err := prepareTmp("/tmp")
@@ -441,18 +489,10 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
441489
return err
442490
}
443491

444-
treeFd, err := unix.OpenTree(-int(unix.EBADF), m.Source, uint(unix.OPEN_TREE_CLONE|unix.OPEN_TREE_CLOEXEC|unix.AT_EMPTY_PATH|unix.AT_RECURSIVE))
445-
if err != nil || treeFd < 0 {
446-
return err
447-
}
448-
449-
err = unix.MoveMount(treeFd, "", unix.AT_FDCWD, dest, unix.MOVE_MOUNT_F_EMPTY_PATH)
450-
if err != nil {
451-
return err
452-
}
453-
454-
if err := mountIDMapMapped(m, treeFd); err != nil {
455-
return err
492+
if mountByMove(m, dest) != nil {
493+
if err := mountPropagate(m, rootfs, mountLabel, mountFd); err != nil {
494+
return err
495+
}
456496
}
457497

458498
// bind mount won't change mount options, we need remount to make mount options effective.

0 commit comments

Comments
 (0)