From 6a252a71410d22eb27ce4893b4b6a7f2cb99956a Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM)" Date: Wed, 1 Aug 2018 09:54:31 -0700 Subject: [PATCH 1/3] IO Windows remove unused wait group Removes an unused and unneeded wait group. Signed-off-by: Justin Terry (VM) --- cio/io_windows.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cio/io_windows.go b/cio/io_windows.go index fa9532a3b..a751f7d7a 100644 --- a/cio/io_windows.go +++ b/cio/io_windows.go @@ -20,7 +20,6 @@ import ( "fmt" "io" "net" - "sync" winio "github.com/Microsoft/go-winio" "github.com/containerd/containerd/log" @@ -41,7 +40,6 @@ func NewFIFOSetInDir(_, id string, terminal bool) (*FIFOSet, error) { func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { var ( - wg sync.WaitGroup set []io.Closer ) @@ -85,9 +83,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { }(l) set = append(set, l) - wg.Add(1) go func() { - defer wg.Done() c, err := l.Accept() if err != nil { log.L.WithError(err).Errorf("failed to accept stdout connection on %s", fifos.Stdout) @@ -115,9 +111,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { }(l) set = append(set, l) - wg.Add(1) go func() { - defer wg.Done() c, err := l.Accept() if err != nil { log.L.WithError(err).Errorf("failed to accept stderr connection on %s", fifos.Stderr) From 790c3a3663d9b6be98825547d05557b90090821f Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM)" Date: Wed, 1 Aug 2018 10:45:07 -0700 Subject: [PATCH 2/3] Remove extra allocation in NewTask Reorders the code so that it doesnt overwrite the previous allocation when creating a NewTask via ctr.exe Signed-off-by: Justin Terry (VM) --- cmd/ctr/commands/tasks/tasks_windows.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/ctr/commands/tasks/tasks_windows.go b/cmd/ctr/commands/tasks/tasks_windows.go index 32dd9e4dc..5235467fc 100644 --- a/cmd/ctr/commands/tasks/tasks_windows.go +++ b/cmd/ctr/commands/tasks/tasks_windows.go @@ -59,15 +59,16 @@ func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Consol // NewTask creates a new task func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, _ string, tty, nullIO bool, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) { - ioCreator := cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...) + var ioCreator cio.Creator if tty { - ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStdio, cio.WithTerminal}, ioOpts...)...) - } - if nullIO { - if tty { + if nullIO { return nil, errors.New("tty and null-io cannot be used together") } + ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStdio, cio.WithTerminal}, ioOpts...)...) + } else if nullIO { ioCreator = cio.NullIO + } else { + ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...) } return container.NewTask(ctx, ioCreator) } From dcb905701c8370f953f9d84301f7a6a9f2203d98 Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM)" Date: Wed, 1 Aug 2018 10:54:53 -0700 Subject: [PATCH 3/3] Adds retry support to Windows AnonDialer Adds retry support to AnonDialer if the pipe does not exist. This will retry up to the timeout for the pipe to exist and connect. This solves the race between the containerd-shim-* start command and the reinvocation. Signed-off-by: Justin Terry (VM) --- runtime/v2/shim/util_windows.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/runtime/v2/shim/util_windows.go b/runtime/v2/shim/util_windows.go index 2e760ed39..be9e661ae 100644 --- a/runtime/v2/shim/util_windows.go +++ b/runtime/v2/shim/util_windows.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "net" + "os" "syscall" "time" @@ -48,7 +49,25 @@ func SocketAddress(ctx context.Context, id string) (string, error) { // AnonDialer returns a dialer for a npipe func AnonDialer(address string, timeout time.Duration) (net.Conn, error) { - return winio.DialPipe(address, &timeout) + var c net.Conn + var lastError error + start := time.Now() + for { + remaining := timeout - time.Now().Sub(start) + if remaining <= 0 { + lastError = errors.Errorf("timed out waiting for npipe %s", address) + break + } + c, lastError = winio.DialPipe(address, &remaining) + if lastError == nil { + break + } + if !os.IsNotExist(lastError) { + break + } + time.Sleep(10 * time.Millisecond) + } + return c, lastError } // NewSocket returns a new npipe listener