overlayutils.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // +build linux
  2. package overlayutils // import "github.com/docker/docker/daemon/graphdriver/overlayutils"
  3. import (
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "path"
  8. "path/filepath"
  9. "github.com/docker/docker/daemon/graphdriver"
  10. "github.com/pkg/errors"
  11. "github.com/sirupsen/logrus"
  12. "golang.org/x/sys/unix"
  13. )
  14. // ErrDTypeNotSupported denotes that the backing filesystem doesn't support d_type.
  15. func ErrDTypeNotSupported(driver, backingFs string) error {
  16. msg := fmt.Sprintf("%s: the backing %s filesystem is formatted without d_type support, which leads to incorrect behavior.", driver, backingFs)
  17. if backingFs == "xfs" {
  18. msg += " Reformat the filesystem with ftype=1 to enable d_type support."
  19. }
  20. if backingFs == "extfs" {
  21. msg += " Reformat the filesystem (or use tune2fs) with -O filetype flag to enable d_type support."
  22. }
  23. msg += " Backing filesystems without d_type support are not supported."
  24. return graphdriver.NotSupportedError(msg)
  25. }
  26. // SupportsOverlay checks if the system supports overlay filesystem
  27. // by performing an actual overlay mount.
  28. //
  29. // checkMultipleLowers parameter enables check for multiple lowerdirs,
  30. // which is required for the overlay2 driver.
  31. func SupportsOverlay(d string, checkMultipleLowers bool) error {
  32. td, err := ioutil.TempDir(d, "check-overlayfs-support")
  33. if err != nil {
  34. return err
  35. }
  36. defer func() {
  37. if err := os.RemoveAll(td); err != nil {
  38. logrus.Warnf("Failed to remove check directory %v: %v", td, err)
  39. }
  40. }()
  41. for _, dir := range []string{"lower1", "lower2", "upper", "work", "merged"} {
  42. if err := os.Mkdir(filepath.Join(td, dir), 0755); err != nil {
  43. return err
  44. }
  45. }
  46. mnt := filepath.Join(td, "merged")
  47. lowerDir := path.Join(td, "lower2")
  48. if checkMultipleLowers {
  49. lowerDir += ":" + path.Join(td, "lower1")
  50. }
  51. opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerDir, path.Join(td, "upper"), path.Join(td, "work"))
  52. if err := unix.Mount("overlay", mnt, "overlay", 0, opts); err != nil {
  53. return errors.Wrap(err, "failed to mount overlay")
  54. }
  55. if err := unix.Unmount(mnt, 0); err != nil {
  56. logrus.Warnf("Failed to unmount check directory %v: %v", mnt, err)
  57. }
  58. return nil
  59. }