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  }