Skip to content

Commit 1c68196

Browse files
Merge pull request #2504 from Luap99/manifest-race
libimage: fix manifest race for AnnotateInstance() and RemoveInstance()
2 parents a7f868d + 18a0916 commit 1c68196

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

libimage/manifest_list.go

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -319,27 +319,16 @@ func (m *ManifestList) saveAndReload() error {
319319
if err != nil {
320320
return err
321321
}
322-
323-
// Make sure to reload the image from the containers storage to fetch
324-
// the latest data (e.g., new or delete digests).
325-
if err := m.image.reload(); err != nil {
326-
return err
327-
}
328-
image, list, err := m.image.runtime.lookupManifestList(newID)
329-
if err != nil {
330-
return err
331-
}
332-
m.image = image
333-
m.list = list
334-
return nil
322+
return m.reloadID(newID)
335323
}
336324

337325
// Reload the image and list instances from storage
338326
func (m *ManifestList) reload() error {
339327
listID := m.ID()
340-
if err := m.image.reload(); err != nil {
341-
return err
342-
}
328+
return m.reloadID(listID)
329+
}
330+
331+
func (m *ManifestList) reloadID(listID string) error {
343332
image, list, err := m.image.runtime.lookupManifestList(listID)
344333
if err != nil {
345334
return err
@@ -669,6 +658,18 @@ func (m *ManifestList) AnnotateInstance(d digest.Digest, options *ManifestListAn
669658
return nil
670659
}
671660

661+
locker, err := manifests.LockerForImage(m.image.runtime.store, m.ID())
662+
if err != nil {
663+
return err
664+
}
665+
locker.Lock()
666+
defer locker.Unlock()
667+
// Make sure to reload the image from the containers storage to fetch
668+
// the latest data (e.g., new or delete digests).
669+
if err := m.reload(); err != nil {
670+
return err
671+
}
672+
672673
if len(options.OS) > 0 {
673674
if err := m.list.SetOS(d, options.OS); err != nil {
674675
return err
@@ -752,6 +753,18 @@ func (m *ManifestList) AnnotateInstance(d digest.Digest, options *ManifestListAn
752753
// RemoveInstance removes the instance specified by `d` from the manifest list.
753754
// Returns the new ID of the image.
754755
func (m *ManifestList) RemoveInstance(d digest.Digest) error {
756+
locker, err := manifests.LockerForImage(m.image.runtime.store, m.ID())
757+
if err != nil {
758+
return err
759+
}
760+
locker.Lock()
761+
defer locker.Unlock()
762+
// Make sure to reload the image from the containers storage to fetch
763+
// the latest data (e.g., new or delete digests).
764+
if err := m.reload(); err != nil {
765+
return err
766+
}
767+
755768
if err := m.list.Remove(d); err != nil {
756769
return err
757770
}

0 commit comments

Comments
 (0)