Browse Source

Add windows graph driver ref counter

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Michael Crosby 9 years ago
parent
commit
4bac8bce98
1 changed files with 32 additions and 1 deletions
  1. 32 1
      daemon/graphdriver/windows/windows.go

+ 32 - 1
daemon/graphdriver/windows/windows.go

@@ -15,11 +15,11 @@ import (
 	"path/filepath"
 	"path/filepath"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
+	"sync"
 	"syscall"
 	"syscall"
 	"time"
 	"time"
 	"unsafe"
 	"unsafe"
 
 
-	"github.com/Microsoft/go-winio"
 	"github.com/Microsoft/go-winio/archive/tar"
 	"github.com/Microsoft/go-winio/archive/tar"
 	"github.com/Microsoft/go-winio/backuptar"
 	"github.com/Microsoft/go-winio/backuptar"
 	"github.com/Microsoft/hcsshim"
 	"github.com/Microsoft/hcsshim"
@@ -31,6 +31,7 @@ import (
 	"github.com/docker/docker/pkg/longpath"
 	"github.com/docker/docker/pkg/longpath"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/pkg/system"
+	"github.com/docker/docker/vendor/src/github.com/Microsoft/go-winio"
 	"github.com/vbatts/tar-split/tar/storage"
 	"github.com/vbatts/tar-split/tar/storage"
 )
 )
 
 
@@ -43,10 +44,22 @@ func init() {
 	reexec.Register("docker-windows-write-layer", writeLayer)
 	reexec.Register("docker-windows-write-layer", writeLayer)
 }
 }
 
 
+type checker struct {
+}
+
+func (c *checker) IsMounted(path string) bool {
+	return false
+}
+
 // Driver represents a windows graph driver.
 // Driver represents a windows graph driver.
 type Driver struct {
 type Driver struct {
 	// info stores the shim driver information
 	// info stores the shim driver information
 	info hcsshim.DriverInfo
 	info hcsshim.DriverInfo
+	ctr  *graphdriver.RefCounter
+	// it is safe for windows to use a cache here because it does not support
+	// restoring containers when the daemon dies.
+	cacheMu sync.Mutex
+	cache   map[string]string
 }
 }
 
 
 func isTP5OrOlder() bool {
 func isTP5OrOlder() bool {
@@ -61,6 +74,8 @@ func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap)
 			HomeDir: home,
 			HomeDir: home,
 			Flavour: filterDriver,
 			Flavour: filterDriver,
 		},
 		},
+		cache: make(map[string]string),
+		ctr:   graphdriver.NewRefCounter(&checker{}),
 	}
 	}
 	return d, nil
 	return d, nil
 }
 }
@@ -211,17 +226,23 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
+	if count := d.ctr.Increment(rID); count > 1 {
+		return d.cache[rID], nil
+	}
 
 
 	// Getting the layer paths must be done outside of the lock.
 	// Getting the layer paths must be done outside of the lock.
 	layerChain, err := d.getLayerChain(rID)
 	layerChain, err := d.getLayerChain(rID)
 	if err != nil {
 	if err != nil {
+		d.ctr.Decrement(rID)
 		return "", err
 		return "", err
 	}
 	}
 
 
 	if err := hcsshim.ActivateLayer(d.info, rID); err != nil {
 	if err := hcsshim.ActivateLayer(d.info, rID); err != nil {
+		d.ctr.Decrement(rID)
 		return "", err
 		return "", err
 	}
 	}
 	if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
 	if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
+		d.ctr.Decrement(rID)
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
 		}
 		}
@@ -230,11 +251,15 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
 
 
 	mountPath, err := hcsshim.GetLayerMountPath(d.info, rID)
 	mountPath, err := hcsshim.GetLayerMountPath(d.info, rID)
 	if err != nil {
 	if err != nil {
+		d.ctr.Decrement(rID)
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
 		}
 		}
 		return "", err
 		return "", err
 	}
 	}
+	d.cacheMu.Lock()
+	d.cache[rID] = mountPath
+	d.cacheMu.Unlock()
 
 
 	// If the layer has a mount path, use that. Otherwise, use the
 	// If the layer has a mount path, use that. Otherwise, use the
 	// folder path.
 	// folder path.
@@ -255,6 +280,12 @@ func (d *Driver) Put(id string) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
+	if count := d.ctr.Decrement(rID); count > 0 {
+		return nil
+	}
+	d.cacheMu.Lock()
+	delete(d.cache, rID)
+	d.cacheMu.Unlock()
 
 
 	if err := hcsshim.UnprepareLayer(d.info, rID); err != nil {
 	if err := hcsshim.UnprepareLayer(d.info, rID); err != nil {
 		return err
 		return err