@@ -26,6 +26,7 @@ import (
2626 "net"
2727 "os"
2828 "os/exec"
29+ "sync"
2930
3031 winio "github.com/Microsoft/go-winio"
3132 "github.com/containerd/containerd/events"
@@ -81,12 +82,51 @@ func handleSignals(logger *logrus.Entry, signals chan os.Signal) error {
8182 }
8283}
8384
85+ type deferredShimWriteLogger struct {
86+ ctx context.Context
87+
88+ wg sync.WaitGroup
89+
90+ c net.Conn
91+ conerr error
92+ }
93+
94+ func (dswl * deferredShimWriteLogger ) Write (p []byte ) (int , error ) {
95+ dswl .wg .Wait ()
96+ if dswl .c == nil {
97+ return 0 , dswl .conerr
98+ }
99+ return dswl .c .Write (p )
100+ }
101+
102+ // openLog on Windows acts as the server of the log pipe. This allows the
103+ // containerd daemon to independently restart and reconnect to the logs.
84104func openLog (ctx context.Context , id string ) (io.Writer , error ) {
85105 ns , err := namespaces .NamespaceRequired (ctx )
86106 if err != nil {
87107 return nil , err
88108 }
89- return winio .DialPipe (fmt .Sprintf ("\\ \\ .\\ pipe\\ containerd-shim-%s-%s-log" , ns , id ), nil )
109+ l , err := winio .ListenPipe (fmt .Sprintf ("\\ \\ .\\ pipe\\ containerd-shim-%s-%s-log" , ns , id ), nil )
110+ if err != nil {
111+ return nil , err
112+ }
113+ dswl := & deferredShimWriteLogger {
114+ ctx : ctx ,
115+ }
116+ // TODO: JTERRY75 - this will not work with restarts. Only the first
117+ // connection will work and all +1 connections will return 'use of closed
118+ // network connection'. Make this reconnect aware.
119+ dswl .wg .Add (1 )
120+ go func () {
121+ c , conerr := l .Accept ()
122+ if conerr != nil {
123+ l .Close ()
124+ dswl .conerr = conerr
125+ }
126+ dswl .c = c
127+ dswl .wg .Done ()
128+ }()
129+ return dswl , nil
90130}
91131
92132func (l * remoteEventsPublisher ) Publish (ctx context.Context , topic string , event events.Event ) error {
0 commit comments