Skip to content

Commit e0124e7

Browse files
committed
tarfs: fix a data race condition
Fix a data race condition WARNING: DATA RACE Write at 0x00c000178428 by goroutine 27: github.com/containerd/nydus-snapshotter/pkg/remote/remotes/docker.(*httpReadSeeker).Close() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/remote/remotes/docker/httpreadseeker.go:87 +0x57 github.com/containerd/nydus-snapshotter/pkg/tarfs.(*Manager).blobProcess.func2.1() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/tarfs/tarfs.go:339 +0x48 runtime.deferreturn() /opt/hostedtoolcache/go/1.20.1/x64/src/runtime/panic.go:476 +0x32 github.com/containerd/nydus-snapshotter/pkg/tarfs.(*Manager).blobProcess.func3() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/tarfs/tarfs.go:394 +0x71 Previous read at 0x00c000178428 by goroutine 40: github.com/containerd/nydus-snapshotter/pkg/remote/remotes/docker.(*httpReadSeeker).Read() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/remote/remotes/docker/httpreadseeker.go:48 +0x68 bufio.(*Reader).Read() /opt/hostedtoolcache/go/1.20.1/x64/src/bufio/bufio.go:223 +0x2c3 github.com/containerd/containerd/archive/compression.(*bufferedReader).Read() /home/runner/go/pkg/mod/github.com/containerd/[email protected]/archive/compression/compression.go:113 +0xa4 io.copyBuffer() /opt/hostedtoolcache/go/1.20.1/x64/src/io/io.go:427 +0x28d io.Copy() /opt/hostedtoolcache/go/1.20.1/x64/src/io/io.go:386 +0x88 os.genericReadFrom() /opt/hostedtoolcache/go/1.20.1/x64/src/os/file.go:161 +0x34 os.(*File).ReadFrom() /opt/hostedtoolcache/go/1.20.1/x64/src/os/file.go:155 +0x324 io.copyBuffer() /opt/hostedtoolcache/go/1.20.1/x64/src/io/io.go:413 +0x1c5 io.Copy() /opt/hostedtoolcache/go/1.20.1/x64/src/io/io.go:386 +0x84 os/exec.(*Cmd).childStdin.func1() /opt/hostedtoolcache/go/1.20.1/x64/src/os/exec/exec.go:511 +0x45 os/exec.(*Cmd).Start.func2() /opt/hostedtoolcache/go/1.20.1/x64/src/os/exec/exec.go:717 +0x42 os/exec.(*Cmd).Start.func3() /opt/hostedtoolcache/go/1.20.1/x64/src/os/exec/exec.go:729 +0x47 Goroutine 27 (running) created at: github.com/containerd/nydus-snapshotter/pkg/tarfs.(*Manager).blobProcess() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/tarfs/tarfs.go:393 +0x9dd github.com/containerd/nydus-snapshotter/pkg/tarfs.(*Manager).PrepareLayer() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/tarfs/tarfs.go:465 +0x444 github.com/containerd/nydus-snapshotter/pkg/tarfs.TestPrepareLayer() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/tarfs/tarfs_test.go:33 +0x188 testing.tRunner() /opt/hostedtoolcache/go/1.20.1/x64/src/testing/testing.go:1576 +0x216 testing.(*T).Run.func1() /opt/hostedtoolcache/go/1.20.1/x64/src/testing/testing.go:1629 +0x47 Goroutine 40 (finished) created at: os/exec.(*Cmd).Start() /opt/hostedtoolcache/go/1.20.1/x64/src/os/exec/exec.go:716 +0xf8e github.com/containerd/containerd/archive/compression.cmdStream() /home/runner/go/pkg/mod/github.com/containerd/[email protected]/archive/compression/compression.go:284 +0x36f github.com/containerd/containerd/archive/compression.gzipDecompress() /home/runner/go/pkg/mod/github.com/containerd/[email protected]/archive/compression/compression.go:272 +0x152 github.com/containerd/containerd/archive/compression.DecompressStream() /home/runner/go/pkg/mod/github.com/containerd/[email protected]/archive/compression/compression.go:203 +0x3e4 github.com/containerd/nydus-snapshotter/pkg/tarfs.(*Manager).blobProcess.func2() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/tarfs/tarfs.go:341 +0x1b1 github.com/containerd/nydus-snapshotter/pkg/tarfs.(*Manager).blobProcess.func3() /home/runner/work/nydus-snapshotter/nydus-snapshotter/pkg/tarfs/tarfs.go:394 +0x71 ================== testing.go:1446: race detected during execution of test Signed-off-by: Jiang Liu <[email protected]>
1 parent 54e2afb commit e0124e7

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

pkg/tarfs/tarfs.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"strings"
2121
"sync"
2222
"syscall"
23+
"time"
2324

2425
"github.com/containerd/containerd/archive/compression"
2526
"github.com/containerd/containerd/log"
@@ -213,7 +214,7 @@ func (t *Manager) getBlobStream(ctx context.Context, remote *remote.Remote, ref
213214
}
214215

215216
// generate tar file and layer bootstrap, return if this blob is an empty blob
216-
func (t *Manager) generateBootstrap(tarReader io.Reader, snapshotID, layerBlobID, upperDirPath string) (err error) {
217+
func (t *Manager) generateBootstrap(tarReader io.Reader, snapshotID, layerBlobID, upperDirPath string, w *sync.WaitGroup) (err error) {
217218
snapshotImageDir := filepath.Join(upperDirPath, "image")
218219
if err := os.MkdirAll(snapshotImageDir, 0750); err != nil {
219220
return errors.Wrapf(err, "create data dir %s for tarfs snapshot", snapshotImageDir)
@@ -235,20 +236,33 @@ func (t *Manager) generateBootstrap(tarReader io.Reader, snapshotID, layerBlobID
235236
defer os.Remove(layerTarFileTmp)
236237

237238
fifoName := filepath.Join(upperDirPath, "layer_"+snapshotID+"_"+"tar.fifo")
238-
if err = syscall.Mkfifo(fifoName, 0644); err != nil {
239+
if err = syscall.Mkfifo(fifoName, 0640); err != nil {
239240
return err
240241
}
241242
defer os.Remove(fifoName)
242243

244+
w.Add(1)
243245
go func() {
244-
fifoFile, err := os.OpenFile(fifoName, os.O_WRONLY, os.ModeNamedPipe)
245-
if err != nil {
246-
log.L.Warnf("can not open fifo file, err %v", err)
247-
return
246+
defer w.Done()
247+
248+
var fifoFile *os.File
249+
for i := 1; i < 100 && fifoFile == nil; i++ {
250+
file, err := os.OpenFile(fifoName, os.O_RDWR, os.ModeNamedPipe)
251+
switch {
252+
case err == nil:
253+
fifoFile = file
254+
case os.IsNotExist(err) || os.IsPermission(err):
255+
log.L.Warnf("open fifo file, %v", err)
256+
return
257+
default:
258+
log.L.Warnf("open fifo file, %v", err)
259+
time.Sleep(time.Duration(i) * 10 * time.Millisecond)
260+
}
248261
}
249262
defer fifoFile.Close()
263+
250264
if _, err := io.Copy(fifoFile, io.TeeReader(tarReader, tarFile)); err != nil {
251-
log.L.Warnf("tar stream copy err %v", err)
265+
log.L.Warnf("tar stream copy, %v", err)
252266
}
253267
}()
254268

@@ -338,6 +352,9 @@ func (t *Manager) blobProcess(ctx context.Context, snapshotID, ref string,
338352
process := func(rc io.ReadCloser, remote *remote.Remote) error {
339353
defer rc.Close()
340354

355+
var w sync.WaitGroup
356+
defer w.Wait()
357+
341358
ds, err := compression.DecompressStream(rc)
342359
if err != nil {
343360
return epilog(err, "unpack layer blob stream for tarfs")
@@ -351,7 +368,7 @@ func (t *Manager) blobProcess(ctx context.Context, snapshotID, ref string,
351368
}
352369
digester := digest.Canonical.Digester()
353370
dr := io.TeeReader(ds, digester.Hash())
354-
err = t.generateBootstrap(dr, snapshotID, layerBlobID, upperDirPath)
371+
err = t.generateBootstrap(dr, snapshotID, layerBlobID, upperDirPath, &w)
355372
switch {
356373
case err != nil && !errdefs.IsAlreadyExists(err):
357374
return epilog(err, "generate tarfs from image layer blob")
@@ -362,7 +379,7 @@ func (t *Manager) blobProcess(ctx context.Context, snapshotID, ref string,
362379
return epilog(nil, msg)
363380
}
364381
} else {
365-
err = t.generateBootstrap(ds, snapshotID, layerBlobID, upperDirPath)
382+
err = t.generateBootstrap(ds, snapshotID, layerBlobID, upperDirPath, &w)
366383
if err != nil && !errdefs.IsAlreadyExists(err) {
367384
return epilog(err, "generate tarfs data from image layer blob")
368385
}

0 commit comments

Comments
 (0)