Remove ref counting from layer store
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
5b6b8df0c1
commit
e19499710e
4 changed files with 3 additions and 116 deletions
|
@ -502,15 +502,9 @@ func (ls *layerStore) ReinitRWLayer(l RWLayer) error {
|
|||
ls.mountL.Lock()
|
||||
defer ls.mountL.Unlock()
|
||||
|
||||
m, ok := ls.mounts[l.Name()]
|
||||
if !ok {
|
||||
if _, ok := ls.mounts[l.Name()]; !ok {
|
||||
return ErrMountDoesNotExist
|
||||
}
|
||||
|
||||
if err := m.incActivityCount(l); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -400,14 +400,11 @@ func TestStoreRestore(t *testing.T) {
|
|||
if err := ioutil.WriteFile(filepath.Join(path, "testfile.txt"), []byte("nothing here"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertActivityCount(t, m, 1)
|
||||
|
||||
if err := m.Unmount(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assertActivityCount(t, m, 0)
|
||||
|
||||
ls2, err := NewStoreFromGraphDriver(ls.(*layerStore).store, ls.(*layerStore).driver)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -438,20 +435,15 @@ func TestStoreRestore(t *testing.T) {
|
|||
t.Fatalf("Unexpected path %s, expected %s", mountPath, path)
|
||||
}
|
||||
|
||||
assertActivityCount(t, m2, 1)
|
||||
|
||||
if mountPath, err := m2.Mount(""); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if path != mountPath {
|
||||
t.Fatalf("Unexpected path %s, expected %s", mountPath, path)
|
||||
}
|
||||
assertActivityCount(t, m2, 2)
|
||||
if err := m2.Unmount(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assertActivityCount(t, m2, 1)
|
||||
|
||||
b, err := ioutil.ReadFile(filepath.Join(path, "testfile.txt"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -464,8 +456,6 @@ func TestStoreRestore(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assertActivityCount(t, m2, 0)
|
||||
|
||||
if metadata, err := ls2.ReleaseRWLayer(m2); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(metadata) != 0 {
|
||||
|
@ -674,13 +664,6 @@ func assertReferences(t *testing.T, references ...Layer) {
|
|||
}
|
||||
}
|
||||
|
||||
func assertActivityCount(t *testing.T, l RWLayer, expected int) {
|
||||
rl := l.(*referencedRWLayer)
|
||||
if rl.activityCount != expected {
|
||||
t.Fatalf("Unexpected activity count %d, expected %d", rl.activityCount, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterExistingLayer(t *testing.T) {
|
||||
ls, _, cleanup := newTestStore(t)
|
||||
defer cleanup()
|
||||
|
|
|
@ -380,8 +380,6 @@ func TestMountMigration(t *testing.T) {
|
|||
Kind: archive.ChangeAdd,
|
||||
})
|
||||
|
||||
assertActivityCount(t, rwLayer1, 1)
|
||||
|
||||
if _, err := ls.CreateRWLayer("migration-mount", layer1.ChainID(), "", nil, nil); err == nil {
|
||||
t.Fatal("Expected error creating mount with same name")
|
||||
} else if err != ErrMountNameConflict {
|
||||
|
@ -401,16 +399,10 @@ func TestMountMigration(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assertActivityCount(t, rwLayer2, 1)
|
||||
assertActivityCount(t, rwLayer1, 1)
|
||||
|
||||
if _, err := rwLayer2.Mount(""); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assertActivityCount(t, rwLayer2, 2)
|
||||
assertActivityCount(t, rwLayer1, 1)
|
||||
|
||||
if metadata, err := ls.Release(layer1); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(metadata) > 0 {
|
||||
|
@ -420,8 +412,6 @@ func TestMountMigration(t *testing.T) {
|
|||
if err := rwLayer1.Unmount(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertActivityCount(t, rwLayer2, 2)
|
||||
assertActivityCount(t, rwLayer1, 0)
|
||||
|
||||
if _, err := ls.ReleaseRWLayer(rwLayer1); err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -430,9 +420,6 @@ func TestMountMigration(t *testing.T) {
|
|||
if err := rwLayer2.Unmount(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := ls.ReleaseRWLayer(rwLayer2); err == nil {
|
||||
t.Fatal("Expected error deleting active mount")
|
||||
}
|
||||
if err := rwLayer2.Unmount(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package layer
|
|||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
)
|
||||
|
@ -83,106 +82,30 @@ func (ml *mountedLayer) hasReferences() bool {
|
|||
return len(ml.references) > 0
|
||||
}
|
||||
|
||||
func (ml *mountedLayer) incActivityCount(ref RWLayer) error {
|
||||
rl, ok := ml.references[ref]
|
||||
if !ok {
|
||||
return ErrLayerNotRetained
|
||||
}
|
||||
|
||||
if err := rl.acquire(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ml *mountedLayer) deleteReference(ref RWLayer) error {
|
||||
rl, ok := ml.references[ref]
|
||||
if !ok {
|
||||
if _, ok := ml.references[ref]; !ok {
|
||||
return ErrLayerNotRetained
|
||||
}
|
||||
|
||||
if err := rl.release(); err != nil {
|
||||
return err
|
||||
}
|
||||
delete(ml.references, ref)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ml *mountedLayer) retakeReference(r RWLayer) {
|
||||
if ref, ok := r.(*referencedRWLayer); ok {
|
||||
ref.activityCount = 0
|
||||
ml.references[ref] = ref
|
||||
}
|
||||
}
|
||||
|
||||
type referencedRWLayer struct {
|
||||
*mountedLayer
|
||||
|
||||
activityL sync.Mutex
|
||||
activityCount int
|
||||
}
|
||||
|
||||
func (rl *referencedRWLayer) acquire() error {
|
||||
rl.activityL.Lock()
|
||||
defer rl.activityL.Unlock()
|
||||
|
||||
rl.activityCount++
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rl *referencedRWLayer) release() error {
|
||||
rl.activityL.Lock()
|
||||
defer rl.activityL.Unlock()
|
||||
|
||||
if rl.activityCount > 0 {
|
||||
return ErrActiveMount
|
||||
}
|
||||
|
||||
rl.activityCount = -1
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rl *referencedRWLayer) Mount(mountLabel string) (string, error) {
|
||||
rl.activityL.Lock()
|
||||
defer rl.activityL.Unlock()
|
||||
|
||||
if rl.activityCount == -1 {
|
||||
return "", ErrLayerNotRetained
|
||||
}
|
||||
|
||||
if rl.activityCount > 0 {
|
||||
rl.activityCount++
|
||||
return rl.path, nil
|
||||
}
|
||||
|
||||
m, err := rl.mountedLayer.Mount(mountLabel)
|
||||
if err == nil {
|
||||
rl.activityCount++
|
||||
rl.path = m
|
||||
}
|
||||
return m, err
|
||||
return rl.mountedLayer.Mount(mountLabel)
|
||||
}
|
||||
|
||||
// Unmount decrements the activity count and unmounts the underlying layer
|
||||
// Callers should only call `Unmount` once per call to `Mount`, even on error.
|
||||
func (rl *referencedRWLayer) Unmount() error {
|
||||
rl.activityL.Lock()
|
||||
defer rl.activityL.Unlock()
|
||||
|
||||
if rl.activityCount == 0 {
|
||||
return ErrNotMounted
|
||||
}
|
||||
if rl.activityCount == -1 {
|
||||
return ErrLayerNotRetained
|
||||
}
|
||||
|
||||
rl.activityCount--
|
||||
if rl.activityCount > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return rl.mountedLayer.Unmount()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue