diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go index fe41ded64c..b3cdbb1795 100644 --- a/daemon/graphdriver/windows/windows.go +++ b/daemon/graphdriver/windows/windows.go @@ -26,23 +26,30 @@ import ( "github.com/microsoft/hcsshim" ) +// init registers the windows graph drivers to the register. func init() { graphdriver.Register("windowsfilter", InitFilter) graphdriver.Register("windowsdiff", InitDiff) } const ( + // diffDriver is an hcsshim driver type diffDriver = iota + // filterDriver is an hcsshim driver type filterDriver ) +// Driver represents a windows graph driver. type Driver struct { - info hcsshim.DriverInfo - sync.Mutex // Protects concurrent modification to active - active map[string]int + // info stores the shim driver information + info hcsshim.DriverInfo + // Mutex protects concurrent modification to active + sync.Mutex + // active stores references to the activated layers + active map[string]int } -// New returns a new Windows storage filter driver. +// InitFilter returns a new Windows storage filter driver. func InitFilter(home string, options []string) (graphdriver.Driver, error) { logrus.Debugf("WindowsGraphDriver InitFilter at %s", home) d := &Driver{ @@ -55,7 +62,7 @@ func InitFilter(home string, options []string) (graphdriver.Driver, error) { return d, nil } -// New returns a new Windows differencing disk driver. +// InitDiff returns a new Windows differencing disk driver. func InitDiff(home string, options []string) (graphdriver.Driver, error) { logrus.Debugf("WindowsGraphDriver InitDiff at %s", home) d := &Driver{ @@ -68,6 +75,7 @@ func InitDiff(home string, options []string) (graphdriver.Driver, error) { return d, nil } +// String returns the string representation of a driver. func (d *Driver) String() string { switch d.info.Flavour { case diffDriver: @@ -79,28 +87,29 @@ func (d *Driver) String() string { } } +// Status returns the status of the driver. func (d *Driver) Status() [][2]string { return [][2]string{ {"Windows", ""}, } } -// Exists returns true if the given id is registered with -// this driver +// Exists returns true if the given id is registered with this driver. func (d *Driver) Exists(id string) bool { - rId, err := d.resolveId(id) + rID, err := d.resolveID(id) if err != nil { return false } - result, err := hcsshim.LayerExists(d.info, rId) + result, err := hcsshim.LayerExists(d.info, rID) if err != nil { return false } return result } +// Create creates a new layer with the given id. func (d *Driver) Create(id, parent string) error { - rPId, err := d.resolveId(parent) + rPId, err := d.resolveID(parent) if err != nil { return err } @@ -154,21 +163,22 @@ func (d *Driver) Create(id, parent string) error { return nil } +// dir returns the absolute path to the layer. func (d *Driver) dir(id string) string { return filepath.Join(d.info.HomeDir, filepath.Base(id)) } -// Remove unmounts and removes the dir information +// Remove unmounts and removes the dir information. func (d *Driver) Remove(id string) error { - rId, err := d.resolveId(id) + rID, err := d.resolveID(id) if err != nil { return err } - return hcsshim.DestroyLayer(d.info, rId) + return hcsshim.DestroyLayer(d.info, rID) } -// Get returns the rootfs path for the id. This will mount the dir at it's given path +// Get returns the rootfs path for the id. This will mount the dir at it's given path. func (d *Driver) Get(id, mountLabel string) (string, error) { logrus.Debugf("WindowsGraphDriver Get() id %s mountLabel %s", id, mountLabel) var dir string @@ -176,38 +186,38 @@ func (d *Driver) Get(id, mountLabel string) (string, error) { d.Lock() defer d.Unlock() - rId, err := d.resolveId(id) + rID, err := d.resolveID(id) if err != nil { return "", err } // Getting the layer paths must be done outside of the lock. - layerChain, err := d.getLayerChain(rId) + layerChain, err := d.getLayerChain(rID) if err != nil { return "", err } - if d.active[rId] == 0 { - if err := hcsshim.ActivateLayer(d.info, rId); err != nil { + if d.active[rID] == 0 { + if err := hcsshim.ActivateLayer(d.info, rID); err != nil { return "", err } - if err := hcsshim.PrepareLayer(d.info, rId, layerChain); err != nil { - if err2 := hcsshim.DeactivateLayer(d.info, rId); err2 != nil { + if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil { + if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil { logrus.Warnf("Failed to Deactivate %s: %s", id, err) } return "", err } } - mountPath, err := hcsshim.GetLayerMountPath(d.info, rId) + mountPath, err := hcsshim.GetLayerMountPath(d.info, rID) if err != nil { - 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) } return "", err } - d.active[rId]++ + d.active[rID]++ // If the layer has a mount path, use that. Otherwise, use the // folder path. @@ -220,10 +230,11 @@ func (d *Driver) Get(id, mountLabel string) (string, error) { return dir, nil } +// Put adds a new layer to the driver. func (d *Driver) Put(id string) error { logrus.Debugf("WindowsGraphDriver Put() id %s", id) - rId, err := d.resolveId(id) + rID, err := d.resolveID(id) if err != nil { return err } @@ -231,21 +242,22 @@ func (d *Driver) Put(id string) error { d.Lock() defer d.Unlock() - if d.active[rId] > 1 { - d.active[rId]-- - } else if d.active[rId] == 1 { - if err := hcsshim.UnprepareLayer(d.info, rId); err != nil { + if d.active[rID] > 1 { + d.active[rID]-- + } else if d.active[rID] == 1 { + if err := hcsshim.UnprepareLayer(d.info, rID); err != nil { return err } - if err := hcsshim.DeactivateLayer(d.info, rId); err != nil { + if err := hcsshim.DeactivateLayer(d.info, rID); err != nil { return err } - delete(d.active, rId) + delete(d.active, rID) } return nil } +// Cleanup ensures the information the driver stores is properly removed. func (d *Driver) Cleanup() error { return nil } @@ -253,13 +265,13 @@ func (d *Driver) Cleanup() error { // Diff produces an archive of the changes between the specified // layer and its parent layer which may be "". func (d *Driver) Diff(id, parent string) (arch archive.Archive, err error) { - rId, err := d.resolveId(id) + rID, err := d.resolveID(id) if err != nil { return } // Getting the layer paths must be done outside of the lock. - layerChain, err := d.getLayerChain(rId) + layerChain, err := d.getLayerChain(rID) if err != nil { return } @@ -268,24 +280,24 @@ func (d *Driver) Diff(id, parent string) (arch archive.Archive, err error) { // To support export, a layer must be activated but not prepared. if d.info.Flavour == filterDriver { - if d.active[rId] == 0 { - if err = hcsshim.ActivateLayer(d.info, rId); err != nil { + if d.active[rID] == 0 { + if err = hcsshim.ActivateLayer(d.info, rID); err != nil { d.Unlock() return } defer func() { - if err := hcsshim.DeactivateLayer(d.info, rId); err != nil { - logrus.Warnf("Failed to Deactivate %s: %s", rId, err) + if err := hcsshim.DeactivateLayer(d.info, rID); err != nil { + logrus.Warnf("Failed to Deactivate %s: %s", rID, err) } }() } else { - if err = hcsshim.UnprepareLayer(d.info, rId); err != nil { + if err = hcsshim.UnprepareLayer(d.info, rID); err != nil { d.Unlock() return } defer func() { - if err := hcsshim.PrepareLayer(d.info, rId, layerChain); err != nil { - logrus.Warnf("Failed to re-PrepareLayer %s: %s", rId, err) + if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil { + logrus.Warnf("Failed to re-PrepareLayer %s: %s", rID, err) } }() } @@ -293,7 +305,7 @@ func (d *Driver) Diff(id, parent string) (arch archive.Archive, err error) { d.Unlock() - return d.exportLayer(rId, layerChain) + return d.exportLayer(rID, layerChain) } // Changes produces a list of changes between the specified layer @@ -306,7 +318,7 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) { // layer with the specified id and parent, returning the size of the // new layer in bytes. func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) { - rPId, err := d.resolveId(parent) + rPId, err := d.resolveID(parent) if err != nil { return } @@ -350,7 +362,7 @@ func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, // and its parent and returns the size in bytes of the changes // relative to its base filesystem directory. func (d *Driver) DiffSize(id, parent string) (size int64, err error) { - rPId, err := d.resolveId(parent) + rPId, err := d.resolveID(parent) if err != nil { return } @@ -369,6 +381,7 @@ func (d *Driver) DiffSize(id, parent string) (size int64, err error) { return archive.ChangesSize(layerFs, changes), nil } +// RestoreCustomImages adds any auto-detected OS specific images to the tag and graph store. func (d *Driver) RestoreCustomImages(tagger graphdriver.Tagger, recorder graphdriver.Recorder) (imageIDs []string, err error) { strData, err := hcsshim.GetSharedBaseImages() if err != nil { @@ -422,7 +435,7 @@ func (d *Driver) RestoreCustomImages(tagger graphdriver.Tagger, recorder graphdr } // Create the alternate ID file. - if err := d.setId(img.ID, folderName); err != nil { + if err := d.setID(img.ID, folderName); err != nil { return nil, err } @@ -433,12 +446,14 @@ func (d *Driver) RestoreCustomImages(tagger graphdriver.Tagger, recorder graphdr return imageIDs, nil } +// GetMetadata returns custom driver information. func (d *Driver) GetMetadata(id string) (map[string]string, error) { m := make(map[string]string) m["dir"] = d.dir(id) return m, nil } +// exportLayer generates an archive from a layer based on the given ID. func (d *Driver) exportLayer(id string, parentLayerPaths []string) (arch archive.Archive, err error) { layerFolder := d.dir(id) @@ -476,6 +491,7 @@ func (d *Driver) exportLayer(id string, parentLayerPaths []string) (arch archive } +// importLayer adds a new layer to the tag and graph store based on the given data. func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPaths []string) (size int64, err error) { layerFolder := d.dir(id) @@ -505,8 +521,9 @@ func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPat return } -func (d *Driver) resolveId(id string) (string, error) { - content, err := ioutil.ReadFile(filepath.Join(d.dir(id), "layerId")) +// resolveID computes the layerID information based on the given id. +func (d *Driver) resolveID(id string) (string, error) { + content, err := ioutil.ReadFile(filepath.Join(d.dir(id), "layerID")) if os.IsNotExist(err) { return id, nil } else if err != nil { @@ -515,14 +532,16 @@ func (d *Driver) resolveId(id string) (string, error) { return string(content), nil } -func (d *Driver) setId(id, altId string) error { - err := ioutil.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altId), 0600) +// setID stores the layerId in disk. +func (d *Driver) setID(id, altID string) error { + err := ioutil.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altID), 0600) if err != nil { return err } return nil } +// getLayerChain returns the layer chain information. func (d *Driver) getLayerChain(id string) ([]string, error) { jPath := filepath.Join(d.dir(id), "layerchain.json") content, err := ioutil.ReadFile(jPath) @@ -541,6 +560,7 @@ func (d *Driver) getLayerChain(id string) ([]string, error) { return layerChain, nil } +// setLayerChain stores the layer chain information in disk. func (d *Driver) setLayerChain(id string, chain []string) error { content, err := json.Marshal(&chain) if err != nil {