github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/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 func (ml *mountedLayer) retakeReference(r RWLayer) { 100 if ref, ok := r.(*referencedRWLayer); ok { 101 ref.activityCount = 0 102 ml.references[ref] = ref 103 } 104 } 105 106 type referencedRWLayer struct { 107 *mountedLayer 108 109 activityL sync.Mutex 110 activityCount int 111 } 112 113 func (rl *referencedRWLayer) release() error { 114 rl.activityL.Lock() 115 defer rl.activityL.Unlock() 116 117 if rl.activityCount > 0 { 118 return ErrActiveMount 119 } 120 121 rl.activityCount = -1 122 123 return nil 124 } 125 126 func (rl *referencedRWLayer) Mount(mountLabel string) (string, error) { 127 rl.activityL.Lock() 128 defer rl.activityL.Unlock() 129 130 if rl.activityCount == -1 { 131 return "", ErrLayerNotRetained 132 } 133 134 rl.activityCount++ 135 return rl.mountedLayer.Mount(mountLabel) 136 } 137 138 func (rl *referencedRWLayer) Unmount() error { 139 rl.activityL.Lock() 140 defer rl.activityL.Unlock() 141 142 if rl.activityCount == 0 { 143 return ErrNotMounted 144 } 145 if rl.activityCount == -1 { 146 return ErrLayerNotRetained 147 } 148 rl.activityCount-- 149 150 return rl.mountedLayer.Unmount() 151 }