mirror of https://github.com/docker/docs.git
Add windows graph driver ref counter
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
e19499710e
commit
4bac8bce98
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue