Skip to content

Commit 1c7eab1

Browse files
committed
Allocate a conhost during Windows service startup
Creating a console for containerd causes it to be inherited by any child processes, which gives us performance and reliability improvements. See comment in code for more information. Another option considered here would be to invoke each child process with the DETACHED_PROCESS flag. This would save us the containerd console allocation. The difficulty of this approach would be ensuring that all process invocation points have had this flag added, and that any future invocations also use the flag. Signed-off-by: Kevin Parsons <[email protected]>
1 parent fdab4f4 commit 1c7eab1

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

cmd/containerd/command/service_windows.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ var (
4545
unregisterServiceFlag bool
4646
runServiceFlag bool
4747

48-
setStdHandle = windows.NewLazySystemDLL("kernel32.dll").NewProc("SetStdHandle")
48+
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
49+
setStdHandle = kernel32.NewProc("SetStdHandle")
50+
allocConsole = kernel32.NewProc("AllocConsole")
4951
oldStderr windows.Handle
5052
panicFile *os.File
5153

@@ -322,6 +324,23 @@ func registerUnregisterService(root string) (bool, error) {
322324
}
323325

324326
if runServiceFlag {
327+
// Allocate a conhost for containerd here. We don't actually use this
328+
// at all in containerd, but it will be inherited by any processes
329+
// containerd executes, so they won't need to allocate their own
330+
// conhosts. This is important for two reasons:
331+
// - Creating a conhost slows down process launch.
332+
// - We have seen reliability issues when launching many processes.
333+
// Sometimes the process invocation will fail due to an error when
334+
// creating the conhost.
335+
//
336+
// This needs to be done before initializing the panic file, as
337+
// AllocConsole sets the stdio handles to point to the new conhost,
338+
// and we want to make sure stderr goes to the panic file.
339+
r, _, err := allocConsole.Call()
340+
if r == 0 && err != nil {
341+
return true, fmt.Errorf("error allocating conhost: %s", err)
342+
}
343+
325344
if err := initPanicFile(filepath.Join(root, "panic.log")); err != nil {
326345
return true, err
327346
}
@@ -341,7 +360,6 @@ func registerUnregisterService(root string) (bool, error) {
341360

342361
logrus.AddHook(&etwHook{log})
343362
logrus.SetOutput(ioutil.Discard)
344-
345363
}
346364
return false, nil
347365
}

0 commit comments

Comments
 (0)