github.com/reds/docker@v1.11.2-rc1/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 path string 16 layerStore *layerStore 17 18 references map[RWLayer]*referencedRWLayer 19 } 20 21 func (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 31 func (ml *mountedLayer) TarStream() (io.ReadCloser, error) { 32 archiver, err := ml.layerStore.driver.Diff(ml.mountID, ml.cacheParent()) 33 if err != nil { 34 return nil, err 35 } 36 return archiver, nil 37 } 38 39 func (ml *mountedLayer) Name() string { 40 return ml.name 41 } 42 43 func (ml *mountedLayer) Parent() Layer { 44 if ml.parent != nil { 45 return ml.parent 46 } 47 48 // Return a nil interface instead of an interface wrapping a nil 49 // pointer. 50 return nil 51 } 52 53 func (ml *mountedLayer) Mount(mountLabel string) (string, error) { 54 return ml.layerStore.driver.Get(ml.mountID, mountLabel) 55 } 56 57 func (ml *mountedLayer) Unmount() error { 58 return ml.layerStore.driver.Put(ml.mountID) 59 } 60 61 func (ml *mountedLayer) Size() (int64, error) { 62 return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent()) 63 } 64 65 func (ml *mountedLayer) Changes() ([]archive.Change, error) { 66 return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent()) 67 } 68 69 func (ml *mountedLayer) Metadata() (map[string]string, error) { 70 return ml.layerStore.driver.GetMetadata(ml.mountID) 71 } 72 73 func (ml *mountedLayer) getReference() RWLayer { 74 ref := &referencedRWLayer{ 75 mountedLayer: ml, 76 } 77 ml.references[ref] = ref 78 79 return ref 80 } 81 82 func (ml *mountedLayer) hasReferences() bool { 83 return len(ml.references) > 0 84 } 85 86 func (ml *mountedLayer) incActivityCount(ref RWLayer) error { 87 rl, ok := ml.references[ref] 88 if !ok { 89 return ErrLayerNotRetained 90 } 91 92 if err := rl.acquire(); err != nil { 93 return err 94 } 95 return nil 96 } 97 98 func (ml *mountedLayer) deleteReference(ref RWLayer) error { 99 rl, ok := ml.references[ref] 100 if !ok { 101 return ErrLayerNotRetained 102 } 103 104 if err := rl.release(); err != nil { 105 return err 106 } 107 delete(ml.references, ref) 108 109 return nil 110 } 111 112 func (ml *mountedLayer) retakeReference(r RWLayer) { 113 if ref, ok := r.(*referencedRWLayer); ok { 114 ref.activityCount = 0 115 ml.references[ref] = ref 116 } 117 } 118 119 type referencedRWLayer struct { 120 *mountedLayer 121 122 activityL sync.Mutex 123 activityCount int 124 } 125 126 func (rl *referencedRWLayer) acquire() error { 127 rl.activityL.Lock() 128 defer rl.activityL.Unlock() 129 130 rl.activityCount++ 131 132 return nil 133 } 134 135 func (rl *referencedRWLayer) release() error { 136 rl.activityL.Lock() 137 defer rl.activityL.Unlock() 138 139 if rl.activityCount > 0 { 140 return ErrActiveMount 141 } 142 143 rl.activityCount = -1 144 145 return nil 146 } 147 148 func (rl *referencedRWLayer) Mount(mountLabel string) (string, error) { 149 rl.activityL.Lock() 150 defer rl.activityL.Unlock() 151 152 if rl.activityCount == -1 { 153 return "", ErrLayerNotRetained 154 } 155 156 if rl.activityCount > 0 { 157 rl.activityCount++ 158 return rl.path, nil 159 } 160 161 m, err := rl.mountedLayer.Mount(mountLabel) 162 if err == nil { 163 rl.activityCount++ 164 rl.path = m 165 } 166 return m, err 167 } 168 169 // Unmount decrements the activity count and unmounts the underlying layer 170 // Callers should only call `Unmount` once per call to `Mount`, even on error. 171 func (rl *referencedRWLayer) Unmount() error { 172 rl.activityL.Lock() 173 defer rl.activityL.Unlock() 174 175 if rl.activityCount == 0 { 176 return ErrNotMounted 177 } 178 if rl.activityCount == -1 { 179 return ErrLayerNotRetained 180 } 181 182 rl.activityCount-- 183 if rl.activityCount > 0 { 184 return nil 185 } 186 187 return rl.mountedLayer.Unmount() 188 }