@@ -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+
334382func 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