driver.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package graphdriver
  2. import (
  3. "errors"
  4. "fmt"
  5. "os"
  6. "path"
  7. "github.com/docker/docker/pkg/archive"
  8. )
  9. type FsMagic uint64
  10. const (
  11. FsMagicBtrfs = FsMagic(0x9123683E)
  12. FsMagicAufs = FsMagic(0x61756673)
  13. )
  14. type InitFunc func(root string, options []string) (Driver, error)
  15. // ProtoDriver defines the basic capabilities of a driver.
  16. // This interface exists solely to be a minimum set of methods
  17. // for client code which choose not to implement the entire Driver
  18. // interface and use the NaiveDiffDriver wrapper constructor.
  19. //
  20. // Use of ProtoDriver directly by client code is not recommended.
  21. type ProtoDriver interface {
  22. // String returns a string representation of this driver.
  23. String() string
  24. // Create creates a new, empty, filesystem layer with the
  25. // specified id and parent. Parent may be "".
  26. Create(id, parent string) error
  27. // Remove attempts to remove the filesystem layer with this id.
  28. Remove(id string) error
  29. // Get returns the mountpoint for the layered filesystem referred
  30. // to by this id. You can optionally specify a mountLabel or "".
  31. // Returns the absolute path to the mounted layered filesystem.
  32. Get(id, mountLabel string) (dir string, err error)
  33. // Put releases the system resources for the specified id,
  34. // e.g, unmounting layered filesystem.
  35. Put(id string)
  36. // Exists returns whether a filesystem layer with the specified
  37. // ID exists on this driver.
  38. Exists(id string) bool
  39. // Status returns a set of key-value pairs which give low
  40. // level diagnostic status about this driver.
  41. Status() [][2]string
  42. // Cleanup performs necessary tasks to release resources
  43. // held by the driver, e.g., unmounting all layered filesystems
  44. // known to this driver.
  45. Cleanup() error
  46. }
  47. // Driver is the interface for layered/snapshot file system drivers.
  48. type Driver interface {
  49. ProtoDriver
  50. // Diff produces an archive of the changes between the specified
  51. // layer and its parent layer which may be "".
  52. Diff(id, parent string) (archive.Archive, error)
  53. // Changes produces a list of changes between the specified layer
  54. // and its parent layer. If parent is "", then all changes will be ADD changes.
  55. Changes(id, parent string) ([]archive.Change, error)
  56. // ApplyDiff extracts the changeset from the given diff into the
  57. // layer with the specified id and parent, returning the size of the
  58. // new layer in bytes.
  59. ApplyDiff(id, parent string, diff archive.ArchiveReader) (bytes int64, err error)
  60. // DiffSize calculates the changes between the specified id
  61. // and its parent and returns the size in bytes of the changes
  62. // relative to its base filesystem directory.
  63. DiffSize(id, parent string) (bytes int64, err error)
  64. }
  65. var (
  66. DefaultDriver string
  67. // All registred drivers
  68. drivers map[string]InitFunc
  69. // Slice of drivers that should be used in an order
  70. priority = []string{
  71. "aufs",
  72. "btrfs",
  73. "devicemapper",
  74. "vfs",
  75. // experimental, has to be enabled manually for now
  76. "overlay",
  77. }
  78. ErrNotSupported = errors.New("driver not supported")
  79. ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
  80. ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
  81. )
  82. func init() {
  83. drivers = make(map[string]InitFunc)
  84. }
  85. func Register(name string, initFunc InitFunc) error {
  86. if _, exists := drivers[name]; exists {
  87. return fmt.Errorf("Name already registered %s", name)
  88. }
  89. drivers[name] = initFunc
  90. return nil
  91. }
  92. func GetDriver(name, home string, options []string) (Driver, error) {
  93. if initFunc, exists := drivers[name]; exists {
  94. return initFunc(path.Join(home, name), options)
  95. }
  96. return nil, ErrNotSupported
  97. }
  98. func New(root string, options []string) (driver Driver, err error) {
  99. for _, name := range []string{os.Getenv("DOCKER_DRIVER"), DefaultDriver} {
  100. if name != "" {
  101. return GetDriver(name, root, options)
  102. }
  103. }
  104. // Check for priority drivers first
  105. for _, name := range priority {
  106. driver, err = GetDriver(name, root, options)
  107. if err != nil {
  108. if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
  109. continue
  110. }
  111. return nil, err
  112. }
  113. return driver, nil
  114. }
  115. // Check all registered drivers if no priority driver is found
  116. for _, initFunc := range drivers {
  117. if driver, err = initFunc(root, options); err != nil {
  118. if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
  119. continue
  120. }
  121. return nil, err
  122. }
  123. return driver, nil
  124. }
  125. return nil, fmt.Errorf("No supported storage backend found")
  126. }