diff options
author | Kevin Krakauer <krakauer@google.com> | 2018-08-22 17:54:18 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-08-22 17:55:15 -0700 |
commit | a78df1d874f376c0924d5a8f91e9e2b5458cca0f (patch) | |
tree | 22606d9a3de58aa068d958c45f8976be206ace63 | |
parent | a7a8d07d7d6bd551d96621ee841b1b0e0f217ca3 (diff) |
runsc: De-flakes container_test TestMultiContainerSanity.
The bug was caused by os.File's finalizer, which closes the file. Because
fsgofer.serve() was passed a file descriptor as an int rather than a os.File,
callers would pass os.File.Fd(), and the os.File would go out of scope. Thus,
the file would get GC'd and finalized nondeterministically, causing failures
when the file was used.
PiperOrigin-RevId: 209861834
Change-Id: Idf24d5c1f04c9b28659e62c97202ab3b4d72e994
-rw-r--r-- | runsc/container/container_test.go | 1 | ||||
-rw-r--r-- | runsc/fsgofer/control.go | 19 |
2 files changed, 10 insertions, 10 deletions
diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index d847dca97..6d84700ce 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -1371,7 +1371,6 @@ func TestAbbreviatedIDs(t *testing.T) { // TestMultiContainerSanity checks that it is possible to run 2 dead-simple // containers in the same sandbox. func TestMultiContainerSanity(t *testing.T) { - t.Skip("Test is flakey.") // TODO: Remove. for _, conf := range configs(all...) { t.Logf("Running test with conf: %+v", conf) diff --git a/runsc/fsgofer/control.go b/runsc/fsgofer/control.go index 8ce8ee8a0..8cb2f67ac 100644 --- a/runsc/fsgofer/control.go +++ b/runsc/fsgofer/control.go @@ -16,6 +16,7 @@ package fsgofer import ( "fmt" + "os" "path/filepath" "sync" @@ -67,13 +68,13 @@ func (cr *Controller) Wait() { } // Serve starts serving each Attacher in ats via its corresponding file -// descriptor in ioFDs. +// descriptor in ioFDs. This takes ownership of the FDs in ioFDs. func (cr *Controller) Serve(ats []p9.Attacher, ioFDs []int) error { if len(ats) != len(ioFDs) { return fmt.Errorf("number of attach points does not match the number of IO FDs (%d and %d)", len(ats), len(ioFDs)) } for i, _ := range ats { - cr.api.serve(ats[i], ioFDs[i]) + cr.api.serve(ats[i], os.NewFile(uintptr(ioFDs[i]), "io fd")) } return nil } @@ -181,23 +182,23 @@ func (api *api) ServeDirectory(req *ServeDirectoryRequest, _ *struct{}) error { ROMount: req.IsReadOnly, LazyOpenForWrite: true, }) - api.serve(at, int(req.FilePayload.Files[0].Fd())) + api.serve(at, req.FilePayload.Files[0]) return nil } // serve begins serving a directory via a file descriptor. -func (api *api) serve(at p9.Attacher, ioFD int) { +func (api *api) serve(at p9.Attacher, ioFile *os.File) { api.p9wg.Add(1) - go func(ioFD int, at p9.Attacher) { - socket, err := unet.NewSocket(ioFD) + go func() { + socket, err := unet.NewSocket(int(ioFile.Fd())) if err != nil { - panic(fmt.Sprintf("err creating server on FD %d: %v", ioFD, err)) + panic(fmt.Sprintf("err creating server on FD %d: %v", ioFile.Fd(), err)) } s := p9.NewServer(at) if err := s.Handle(socket); err != nil { - panic(fmt.Sprintf("P9 server returned error. Gofer is shutting down. FD: %d, err: %v", ioFD, err)) + panic(fmt.Sprintf("P9 server returned error. Gofer is shutting down. FD: %d, err: %v", ioFile.Fd(), err)) } api.p9wg.Done() - }(ioFD, at) + }() } |