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  }