Browse code

Add windows graph driver ref counter

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Michael Crosby authored on 2016/05/11 03:42:03
Showing 1 changed files
... ...
@@ -15,11 +15,11 @@ import (
15 15
 	"path/filepath"
16 16
 	"strconv"
17 17
 	"strings"
18
+	"sync"
18 19
 	"syscall"
19 20
 	"time"
20 21
 	"unsafe"
21 22
 
22
-	"github.com/Microsoft/go-winio"
23 23
 	"github.com/Microsoft/go-winio/archive/tar"
24 24
 	"github.com/Microsoft/go-winio/backuptar"
25 25
 	"github.com/Microsoft/hcsshim"
... ...
@@ -31,6 +31,7 @@ import (
31 31
 	"github.com/docker/docker/pkg/longpath"
32 32
 	"github.com/docker/docker/pkg/reexec"
33 33
 	"github.com/docker/docker/pkg/system"
34
+	"github.com/docker/docker/vendor/src/github.com/Microsoft/go-winio"
34 35
 	"github.com/vbatts/tar-split/tar/storage"
35 36
 )
36 37
 
... ...
@@ -43,10 +44,22 @@ func init() {
43 43
 	reexec.Register("docker-windows-write-layer", writeLayer)
44 44
 }
45 45
 
46
+type checker struct {
47
+}
48
+
49
+func (c *checker) IsMounted(path string) bool {
50
+	return false
51
+}
52
+
46 53
 // Driver represents a windows graph driver.
47 54
 type Driver struct {
48 55
 	// info stores the shim driver information
49 56
 	info hcsshim.DriverInfo
57
+	ctr  *graphdriver.RefCounter
58
+	// it is safe for windows to use a cache here because it does not support
59
+	// restoring containers when the daemon dies.
60
+	cacheMu sync.Mutex
61
+	cache   map[string]string
50 62
 }
51 63
 
52 64
 func isTP5OrOlder() bool {
... ...
@@ -61,6 +74,8 @@ func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap)
61 61
 			HomeDir: home,
62 62
 			Flavour: filterDriver,
63 63
 		},
64
+		cache: make(map[string]string),
65
+		ctr:   graphdriver.NewRefCounter(&checker{}),
64 66
 	}
65 67
 	return d, nil
66 68
 }
... ...
@@ -211,17 +226,23 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
211 211
 	if err != nil {
212 212
 		return "", err
213 213
 	}
214
+	if count := d.ctr.Increment(rID); count > 1 {
215
+		return d.cache[rID], nil
216
+	}
214 217
 
215 218
 	// Getting the layer paths must be done outside of the lock.
216 219
 	layerChain, err := d.getLayerChain(rID)
217 220
 	if err != nil {
221
+		d.ctr.Decrement(rID)
218 222
 		return "", err
219 223
 	}
220 224
 
221 225
 	if err := hcsshim.ActivateLayer(d.info, rID); err != nil {
226
+		d.ctr.Decrement(rID)
222 227
 		return "", err
223 228
 	}
224 229
 	if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
230
+		d.ctr.Decrement(rID)
225 231
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
226 232
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
227 233
 		}
... ...
@@ -230,11 +251,15 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
230 230
 
231 231
 	mountPath, err := hcsshim.GetLayerMountPath(d.info, rID)
232 232
 	if err != nil {
233
+		d.ctr.Decrement(rID)
233 234
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
234 235
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
235 236
 		}
236 237
 		return "", err
237 238
 	}
239
+	d.cacheMu.Lock()
240
+	d.cache[rID] = mountPath
241
+	d.cacheMu.Unlock()
238 242
 
239 243
 	// If the layer has a mount path, use that. Otherwise, use the
240 244
 	// folder path.
... ...
@@ -255,6 +280,12 @@ func (d *Driver) Put(id string) error {
255 255
 	if err != nil {
256 256
 		return err
257 257
 	}
258
+	if count := d.ctr.Decrement(rID); count > 0 {
259
+		return nil
260
+	}
261
+	d.cacheMu.Lock()
262
+	delete(d.cache, rID)
263
+	d.cacheMu.Unlock()
258 264
 
259 265
 	if err := hcsshim.UnprepareLayer(d.info, rID); err != nil {
260 266
 		return err