github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/layer/mounted_layer.go (about) 1 package layer 2 3 import ( 4 "io" 5 "sync" 6 7 "github.com/docker/docker/pkg/archive" 8 ) 9 10 type mountedLayer struct { 11 name string 12 mountID string 13 initID string 14 parent *roLayer 15 layerStore *layerStore 16 17 references map[RWLayer]*referencedRWLayer 18 } 19 20 func (ml *mountedLayer) cacheParent() string { 21 if ml.initID != "" { 22 return ml.initID 23 } 24 if ml.parent != nil { 25 return ml.parent.cacheID 26 } 27 return "" 28 } 29 30 func (ml *mountedLayer) TarStream() (io.ReadCloser, error) { 31 archiver, err := ml.layerStore.driver.Diff(ml.mountID, ml.cacheParent()) 32 if err != nil { 33 return nil, err 34 } 35 return archiver, nil 36 } 37 38 func (ml *mountedLayer) Name() string { 39 return ml.name 40 } 41 42 func (ml *mountedLayer) Parent() Layer { 43 if ml.parent != nil { 44 return ml.parent 45 } 46 47 // Return a nil interface instead of an interface wrapping a nil 48 // pointer. 49 return nil 50 } 51 52 func (ml *mountedLayer) Mount(mountLabel string) (string, error) { 53 return ml.layerStore.driver.Get(ml.mountID, mountLabel) 54 } 55 56 func (ml *mountedLayer) Unmount() error { 57 return ml.layerStore.driver.Put(ml.mountID) 58 } 59 60 func (ml *mountedLayer) Size() (int64, error) { 61 return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent()) 62 } 63 64 func (ml *mountedLayer) Changes() ([]archive.Change, error) { 65 return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent()) 66 } 67 68 func (ml *mountedLayer) Metadata() (map[string]string, error) { 69 return ml.layerStore.driver.GetMetadata(ml.mountID) 70 } 71 72 func (ml *mountedLayer) getReference() RWLayer { 73 ref := &referencedRWLayer{ 74 mountedLayer: ml, 75 } 76 ml.references[ref] = ref 77 78 return ref 79 } 80 81 func (ml *mountedLayer) hasReferences() bool { 82 return len(ml.references) > 0 83 } 84 85 func (ml *mountedLayer) deleteReference(ref RWLayer) error { 86 rl, ok := ml.references[ref] 87 if !ok { 88 return ErrLayerNotRetained 89 } 90 91 if err := rl.release(); err != nil { 92 return err 93 } 94 delete(ml.references, ref) 95 96 return nil 97 } 98 99 type referencedRWLayer struct { 100 *mountedLayer 101 102 activityL sync.Mutex 103 activityCount int 104 } 105 106 func (rl *referencedRWLayer) release() error { 107 rl.activityL.Lock() 108 defer rl.activityL.Unlock() 109 110 if rl.activityCount > 0 { 111 return ErrActiveMount 112 } 113 114 rl.activityCount = -1 115 116 return nil 117 } 118 119 func (rl *referencedRWLayer) Mount(mountLabel string) (string, error) { 120 rl.activityL.Lock() 121 defer rl.activityL.Unlock() 122 123 if rl.activityCount == -1 { 124 return "", ErrLayerNotRetained 125 } 126 127 rl.activityCount++ 128 return rl.mountedLayer.Mount(mountLabel) 129 } 130 131 func (rl *referencedRWLayer) Unmount() error { 132 rl.activityL.Lock() 133 defer rl.activityL.Unlock() 134 135 if rl.activityCount == 0 { 136 return ErrNotMounted 137 } 138 if rl.activityCount == -1 { 139 return ErrLayerNotRetained 140 } 141 rl.activityCount-- 142 143 return rl.mountedLayer.Unmount() 144 }