github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/daemon/graphdriver/overlayutils/overlayutils.go (about) 1 //go:build linux 2 // +build linux 3 4 package overlayutils // import "github.com/docker/docker/daemon/graphdriver/overlayutils" 5 6 import ( 7 "fmt" 8 "os" 9 "path" 10 "path/filepath" 11 12 "github.com/docker/docker/daemon/graphdriver" 13 "github.com/pkg/errors" 14 "github.com/sirupsen/logrus" 15 "golang.org/x/sys/unix" 16 ) 17 18 // ErrDTypeNotSupported denotes that the backing filesystem doesn't support d_type. 19 func ErrDTypeNotSupported(driver, backingFs string) error { 20 msg := fmt.Sprintf("%s: the backing %s filesystem is formatted without d_type support, which leads to incorrect behavior.", driver, backingFs) 21 if backingFs == "xfs" { 22 msg += " Reformat the filesystem with ftype=1 to enable d_type support." 23 } 24 25 if backingFs == "extfs" { 26 msg += " Reformat the filesystem (or use tune2fs) with -O filetype flag to enable d_type support." 27 } 28 29 msg += " Backing filesystems without d_type support are not supported." 30 31 return graphdriver.NotSupportedError(msg) 32 } 33 34 // SupportsOverlay checks if the system supports overlay filesystem 35 // by performing an actual overlay mount. 36 // 37 // checkMultipleLowers parameter enables check for multiple lowerdirs, 38 // which is required for the overlay2 driver. 39 func SupportsOverlay(d string, checkMultipleLowers bool) error { 40 // We can't rely on go-selinux.GetEnabled() to detect whether SELinux is enabled, 41 // because RootlessKit doesn't mount /sys/fs/selinux in the child: https://github.com/rootless-containers/rootlesskit/issues/94 42 // So we check $_DOCKERD_ROOTLESS_SELINUX, which is set by dockerd-rootless.sh . 43 if os.Getenv("_DOCKERD_ROOTLESS_SELINUX") == "1" { 44 // Kernel 5.11 introduced support for rootless overlayfs, but incompatible with SELinux, 45 // so fallback to fuse-overlayfs. 46 // https://github.com/moby/moby/issues/42333 47 return errors.New("overlay is not supported for Rootless with SELinux") 48 } 49 50 td, err := os.MkdirTemp(d, "check-overlayfs-support") 51 if err != nil { 52 return err 53 } 54 defer func() { 55 if err := os.RemoveAll(td); err != nil { 56 logrus.Warnf("Failed to remove check directory %v: %v", td, err) 57 } 58 }() 59 60 for _, dir := range []string{"lower1", "lower2", "upper", "work", "merged"} { 61 if err := os.Mkdir(filepath.Join(td, dir), 0755); err != nil { 62 return err 63 } 64 } 65 66 mnt := filepath.Join(td, "merged") 67 lowerDir := path.Join(td, "lower2") 68 if checkMultipleLowers { 69 lowerDir += ":" + path.Join(td, "lower1") 70 } 71 opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerDir, path.Join(td, "upper"), path.Join(td, "work")) 72 if err := unix.Mount("overlay", mnt, "overlay", 0, opts); err != nil { 73 return errors.Wrap(err, "failed to mount overlay") 74 } 75 if err := unix.Unmount(mnt, 0); err != nil { 76 logrus.Warnf("Failed to unmount check directory %v: %v", mnt, err) 77 } 78 return nil 79 }