mirror of https://github.com/docker/docs.git
				
				
				
			Remove ref counting from layer store
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
		
							parent
							
								
									5b6b8df0c1
								
							
						
					
					
						commit
						e19499710e
					
				|  | @ -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…
	
		Reference in New Issue