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