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  }