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