1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Mitigate parallel pull issues

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi 2015-08-20 10:25:06 -07:00
parent 137df3048c
commit b779bc3102

View file

@ -224,6 +224,7 @@ func (graph *Graph) Create(layerData io.Reader, containerID, containerImage, com
} }
// Register imports a pre-existing image into the graph. // Register imports a pre-existing image into the graph.
// Returns nil if the image is already registered.
func (graph *Graph) Register(img *image.Image, layerData io.Reader) (err error) { func (graph *Graph) Register(img *image.Image, layerData io.Reader) (err error) {
if err := image.ValidateID(img.ID); err != nil { if err := image.ValidateID(img.ID); err != nil {
@ -235,6 +236,11 @@ func (graph *Graph) Register(img *image.Image, layerData io.Reader) (err error)
graph.imageMutex.Lock(img.ID) graph.imageMutex.Lock(img.ID)
defer graph.imageMutex.Unlock(img.ID) defer graph.imageMutex.Unlock(img.ID)
// Skip register if image is already registered
if graph.Exists(img.ID) {
return nil
}
// The returned `error` must be named in this function's signature so that // The returned `error` must be named in this function's signature so that
// `err` is not shadowed in this deferred cleanup. // `err` is not shadowed in this deferred cleanup.
defer func() { defer func() {
@ -245,11 +251,6 @@ func (graph *Graph) Register(img *image.Image, layerData io.Reader) (err error)
} }
}() }()
// (This is a convenience to save time. Race conditions are taken care of by os.Rename)
if graph.Exists(img.ID) {
return fmt.Errorf("Image %s already exists", img.ID)
}
// Ensure that the image root does not exist on the filesystem // Ensure that the image root does not exist on the filesystem
// when it is not registered in the graph. // when it is not registered in the graph.
// This is common when you switch from one graph driver to another // This is common when you switch from one graph driver to another
@ -517,6 +518,9 @@ func (graph *Graph) saveSize(root string, size int64) error {
// SetDigest sets the digest for the image layer to the provided value. // SetDigest sets the digest for the image layer to the provided value.
func (graph *Graph) SetDigest(id string, dgst digest.Digest) error { func (graph *Graph) SetDigest(id string, dgst digest.Digest) error {
graph.imageMutex.Lock(id)
defer graph.imageMutex.Unlock(id)
root := graph.imageRoot(id) root := graph.imageRoot(id)
if err := ioutil.WriteFile(filepath.Join(root, digestFileName), []byte(dgst.String()), 0600); err != nil { if err := ioutil.WriteFile(filepath.Join(root, digestFileName), []byte(dgst.String()), 0600); err != nil {
return fmt.Errorf("Error storing digest in %s/%s: %s", root, digestFileName, err) return fmt.Errorf("Error storing digest in %s/%s: %s", root, digestFileName, err)
@ -526,6 +530,9 @@ func (graph *Graph) SetDigest(id string, dgst digest.Digest) error {
// GetDigest gets the digest for the provide image layer id. // GetDigest gets the digest for the provide image layer id.
func (graph *Graph) GetDigest(id string) (digest.Digest, error) { func (graph *Graph) GetDigest(id string) (digest.Digest, error) {
graph.imageMutex.Lock(id)
defer graph.imageMutex.Unlock(id)
root := graph.imageRoot(id) root := graph.imageRoot(id)
cs, err := ioutil.ReadFile(filepath.Join(root, digestFileName)) cs, err := ioutil.ReadFile(filepath.Join(root, digestFileName))
if err != nil { if err != nil {