1package layer // import "github.com/docker/docker/layer" 2 3import ( 4 "io" 5 6 "github.com/docker/docker/pkg/archive" 7 "github.com/docker/docker/pkg/containerfs" 8) 9 10type mountedLayer struct { 11 name string 12 mountID string 13 initID string 14 parent *roLayer 15 path string 16 layerStore *layerStore 17 18 references map[RWLayer]*referencedRWLayer 19} 20 21func (ml *mountedLayer) cacheParent() string { 22 if ml.initID != "" { 23 return ml.initID 24 } 25 if ml.parent != nil { 26 return ml.parent.cacheID 27 } 28 return "" 29} 30 31func (ml *mountedLayer) TarStream() (io.ReadCloser, error) { 32 return ml.layerStore.driver.Diff(ml.mountID, ml.cacheParent()) 33} 34 35func (ml *mountedLayer) Name() string { 36 return ml.name 37} 38 39func (ml *mountedLayer) Parent() Layer { 40 if ml.parent != nil { 41 return ml.parent 42 } 43 44 // Return a nil interface instead of an interface wrapping a nil 45 // pointer. 46 return nil 47} 48 49func (ml *mountedLayer) Size() (int64, error) { 50 return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent()) 51} 52 53func (ml *mountedLayer) Changes() ([]archive.Change, error) { 54 return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent()) 55} 56 57func (ml *mountedLayer) Metadata() (map[string]string, error) { 58 return ml.layerStore.driver.GetMetadata(ml.mountID) 59} 60 61func (ml *mountedLayer) getReference() RWLayer { 62 ref := &referencedRWLayer{ 63 mountedLayer: ml, 64 } 65 ml.references[ref] = ref 66 67 return ref 68} 69 70func (ml *mountedLayer) hasReferences() bool { 71 return len(ml.references) > 0 72} 73 74func (ml *mountedLayer) deleteReference(ref RWLayer) error { 75 if _, ok := ml.references[ref]; !ok { 76 return ErrLayerNotRetained 77 } 78 delete(ml.references, ref) 79 return nil 80} 81 82func (ml *mountedLayer) retakeReference(r RWLayer) { 83 if ref, ok := r.(*referencedRWLayer); ok { 84 ml.references[ref] = ref 85 } 86} 87 88type referencedRWLayer struct { 89 *mountedLayer 90} 91 92func (rl *referencedRWLayer) Mount(mountLabel string) (containerfs.ContainerFS, error) { 93 return rl.layerStore.driver.Get(rl.mountedLayer.mountID, mountLabel) 94} 95 96// Unmount decrements the activity count and unmounts the underlying layer 97// Callers should only call `Unmount` once per call to `Mount`, even on error. 98func (rl *referencedRWLayer) Unmount() error { 99 return rl.layerStore.driver.Put(rl.mountedLayer.mountID) 100} 101