From b4211d94e250f4d25b9f51838cc1648666c33828 Mon Sep 17 00:00:00 2001 From: Kathryn Baldauf Date: Fri, 13 Sep 2019 17:25:48 -0700 Subject: [PATCH] fail on file not found for shim reconnect on containerd restart Signed-off-by: Kathryn Baldauf --- runtime/v2/binary.go | 2 +- runtime/v2/shim.go | 4 ++-- runtime/v2/shim/util_unix.go | 4 ++++ runtime/v2/shim/util_windows.go | 16 ++++++++++++++++ runtime/v2/shim_unix.go | 4 +++- runtime/v2/shim_windows.go | 5 ++--- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/runtime/v2/binary.go b/runtime/v2/binary.go index 5e4b85f6a..4e43e1bcf 100644 --- a/runtime/v2/binary.go +++ b/runtime/v2/binary.go @@ -74,7 +74,7 @@ func (b *binary) Start(ctx context.Context, opts *types.Any, onClose func()) (_ if err != nil { return nil, err } - f, err := openShimLog(ctx, b.bundle) + f, err := openShimLog(ctx, b.bundle, client.AnonDialer) if err != nil { return nil, errors.Wrap(err, "open shim log pipe") } diff --git a/runtime/v2/shim.go b/runtime/v2/shim.go index 6635008dc..972f8222f 100644 --- a/runtime/v2/shim.go +++ b/runtime/v2/shim.go @@ -67,7 +67,7 @@ func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt if err != nil { return nil, err } - conn, err := client.Connect(address, client.AnonDialer) + conn, err := client.Connect(address, client.AnonReconnectDialer) if err != nil { return nil, err } @@ -76,7 +76,7 @@ func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt conn.Close() } }() - f, err := openShimLog(ctx, bundle) + f, err := openShimLog(ctx, bundle, client.AnonReconnectDialer) if err != nil { return nil, errors.Wrap(err, "open shim log pipe") } diff --git a/runtime/v2/shim/util_unix.go b/runtime/v2/shim/util_unix.go index 700c5b36b..7ca65033f 100644 --- a/runtime/v2/shim/util_unix.go +++ b/runtime/v2/shim/util_unix.go @@ -78,6 +78,10 @@ func AnonDialer(address string, timeout time.Duration) (net.Conn, error) { return net.DialTimeout("unix", "\x00"+address, timeout) } +func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) { + return AnonDialer(address, timeout) +} + // NewSocket returns a new socket func NewSocket(address string) (*net.UnixListener, error) { if len(address) > 106 { diff --git a/runtime/v2/shim/util_windows.go b/runtime/v2/shim/util_windows.go index 1950ea4a8..a94cdf250 100644 --- a/runtime/v2/shim/util_windows.go +++ b/runtime/v2/shim/util_windows.go @@ -33,6 +33,22 @@ func getSysProcAttr() *syscall.SysProcAttr { return nil } +// AnonReconnectDialer returns a dialer for an existing npipe on containerd reconnection +func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + c, err := winio.DialPipeContext(ctx, address) + if os.IsNotExist(err) { + return nil, errors.Wrap(os.ErrNotExist, "npipe not found on reconnect") + } else if err == context.DeadlineExceeded { + return nil, errors.Wrapf(err, "timed out waiting for npipe %s", address) + } else if err != nil { + return nil, err + } + return c, nil +} + // AnonDialer returns a dialer for a npipe func AnonDialer(address string, timeout time.Duration) (net.Conn, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) diff --git a/runtime/v2/shim_unix.go b/runtime/v2/shim_unix.go index 242a29d35..16e9c7be3 100644 --- a/runtime/v2/shim_unix.go +++ b/runtime/v2/shim_unix.go @@ -21,13 +21,15 @@ package v2 import ( "context" "io" + "net" "path/filepath" + "time" "github.com/containerd/fifo" "golang.org/x/sys/unix" ) -func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) { +func openShimLog(ctx context.Context, bundle *Bundle, _ func(string, time.Duration) (net.Conn, error)) (io.ReadCloser, error) { return fifo.OpenFifo(ctx, filepath.Join(bundle.Path, "log"), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) } diff --git a/runtime/v2/shim_windows.go b/runtime/v2/shim_windows.go index 12baef637..e82e623f6 100644 --- a/runtime/v2/shim_windows.go +++ b/runtime/v2/shim_windows.go @@ -26,7 +26,6 @@ import ( "time" "github.com/containerd/containerd/namespaces" - client "github.com/containerd/containerd/runtime/v2/shim" "github.com/pkg/errors" ) @@ -64,7 +63,7 @@ func (dpc *deferredPipeConnection) Close() error { // openShimLog on Windows acts as the client of the log pipe. In this way the // containerd daemon can reconnect to the shim log stream if it is restarted. -func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) { +func openShimLog(ctx context.Context, bundle *Bundle, dialer func(string, time.Duration) (net.Conn, error)) (io.ReadCloser, error) { ns, err := namespaces.NamespaceRequired(ctx) if err != nil { return nil, err @@ -74,7 +73,7 @@ func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) { } dpc.wg.Add(1) go func() { - c, conerr := client.AnonDialer( + c, conerr := dialer( fmt.Sprintf("\\\\.\\pipe\\containerd-shim-%s-%s-log", ns, bundle.ID), time.Second*10, )