Browse code

Mitigate parallel pull issues

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>

Tonis Tiigi authored on 2015/08/21 02:25:06
Showing 1 changed files
... ...
@@ -224,6 +224,7 @@ func (graph *Graph) Create(layerData io.Reader, containerID, containerImage, com
224 224
 }
225 225
 
226 226
 // Register imports a pre-existing image into the graph.
227
+// Returns nil if the image is already registered.
227 228
 func (graph *Graph) Register(img *image.Image, layerData io.Reader) (err error) {
228 229
 
229 230
 	if err := image.ValidateID(img.ID); err != nil {
... ...
@@ -235,6 +236,11 @@ func (graph *Graph) Register(img *image.Image, layerData io.Reader) (err error)
235 235
 	graph.imageMutex.Lock(img.ID)
236 236
 	defer graph.imageMutex.Unlock(img.ID)
237 237
 
238
+	// Skip register if image is already registered
239
+	if graph.Exists(img.ID) {
240
+		return nil
241
+	}
242
+
238 243
 	// The returned `error` must be named in this function's signature so that
239 244
 	// `err` is not shadowed in this deferred cleanup.
240 245
 	defer func() {
... ...
@@ -245,11 +251,6 @@ func (graph *Graph) Register(img *image.Image, layerData io.Reader) (err error)
245 245
 		}
246 246
 	}()
247 247
 
248
-	// (This is a convenience to save time. Race conditions are taken care of by os.Rename)
249
-	if graph.Exists(img.ID) {
250
-		return fmt.Errorf("Image %s already exists", img.ID)
251
-	}
252
-
253 248
 	// Ensure that the image root does not exist on the filesystem
254 249
 	// when it is not registered in the graph.
255 250
 	// 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 {
517 517
 
518 518
 // SetDigest sets the digest for the image layer to the provided value.
519 519
 func (graph *Graph) SetDigest(id string, dgst digest.Digest) error {
520
+	graph.imageMutex.Lock(id)
521
+	defer graph.imageMutex.Unlock(id)
522
+
520 523
 	root := graph.imageRoot(id)
521 524
 	if err := ioutil.WriteFile(filepath.Join(root, digestFileName), []byte(dgst.String()), 0600); err != nil {
522 525
 		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 {
526 526
 
527 527
 // GetDigest gets the digest for the provide image layer id.
528 528
 func (graph *Graph) GetDigest(id string) (digest.Digest, error) {
529
+	graph.imageMutex.Lock(id)
530
+	defer graph.imageMutex.Unlock(id)
531
+
529 532
 	root := graph.imageRoot(id)
530 533
 	cs, err := ioutil.ReadFile(filepath.Join(root, digestFileName))
531 534
 	if err != nil {