1
0
mirror of https://github.com/moby/buildkit.git synced 2025-04-18 18:04:03 +03:00

Merge pull request #5885 from profnandaa/fix-5807-localmounter-race

fix: wcow: fix race condition in localmounter
This commit is contained in:
Tõnis Tiigi 2025-04-03 13:51:44 -07:00 committed by GitHub
commit 7e2b28d032
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,6 +2,8 @@ package snapshot
import (
"os"
"strings"
"time"
"github.com/Microsoft/go-winio/pkg/bindfilter"
"github.com/containerd/containerd/v2/core/mount"
@ -46,11 +48,15 @@ func (lm *localMounter) Mount() (string, error) {
// The Windows snapshotter does not have any notion of bind mounts. We emulate
// bind mounts here using the bind filter.
if err := bindfilter.ApplyFileBinding(dir, m.Source, m.ReadOnly()); err != nil {
return "", errors.Wrapf(err, "failed to mount %v: %+v", m, err)
return "", errors.Wrapf(err, "failed to mount %v", m)
}
} else {
if err := m.Mount(dir); err != nil {
return "", errors.Wrapf(err, "failed to mount %v: %+v", m, err)
// see https://github.com/moby/buildkit/issues/5807
// if it's a race condition issue, do max 2 retries with some backoff
// should adjust the retries if this persists but 1 retry
// seems to be enough.
if err := mountWithRetries(m, dir, 2); err != nil {
return "", errors.Wrapf(err, "failed to mount %v", m)
}
}
@ -58,6 +64,27 @@ func (lm *localMounter) Mount() (string, error) {
return lm.target, nil
}
func mountWithRetries(m mount.Mount, dir string, retries int) error {
errStr := "cannot access the file because it is being used by another process"
backoff := 30 * time.Millisecond
var err error
for i := range retries + 1 {
// i = 0 is first call and not a retry
err = m.Mount(dir)
if err == nil || i == retries {
return err
}
if strings.Contains(err.Error(), errStr) {
time.Sleep(time.Duration(i+1) * backoff)
} else {
return err
}
}
return err
}
func (lm *localMounter) Unmount() error {
lm.mu.Lock()
defer lm.mu.Unlock()