From 55a367d2fe2feecf7b95fbddcdcb3ed179c197fe Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Thu, 5 May 2016 14:03:28 -0700 Subject: [PATCH] Ignore SIGPIPE events, resolves #19728 Using golang 1.6, is it now possible to ignore SIGPIPE events on stdout/stderr. Previous versions of the golang library cached 10 events and then killed the process receiving the events. systemd-journald sends SIGPIPE events when jounald is restarted and the target of the unit file writes to stdout/stderr. Docker logs to stdout/stderr. This patch silently ignores all SIGPIPE events. Signed-off-by: Jhon Honce --- cmd/dockerd/daemon.go | 10 +++++----- pkg/signal/trap.go | 11 +++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 3df9400a98..cdbdefc418 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -127,6 +127,11 @@ func (cli *DaemonCli) start() (err error) { stopc := make(chan bool) defer close(stopc) + signal.Trap(func() { + cli.stop() + <-stopc // wait for daemonCli.start() to return + }) + // warn from uuid package when running the daemon uuid.Loggerf = logrus.Warnf @@ -280,11 +285,6 @@ func (cli *DaemonCli) start() (err error) { serveAPIWait := make(chan error) go api.Wait(serveAPIWait) - signal.Trap(func() { - cli.stop() - <-stopc // wait for daemonCli.start() to return - }) - // after the daemon is done setting up we can notify systemd api notifySystem() diff --git a/pkg/signal/trap.go b/pkg/signal/trap.go index 2cf5ccf0d2..874509e714 100644 --- a/pkg/signal/trap.go +++ b/pkg/signal/trap.go @@ -18,15 +18,22 @@ import ( // * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is // skipped and the process is terminated immediately (allows force quit of stuck daemon) // * A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit. +// * Ignore SIGPIPE events. These are generated by systemd when journald is restarted while +// the docker daemon is not restarted and also running under systemd. +// Fixes https://github.com/docker/docker/issues/19728 // func Trap(cleanup func()) { c := make(chan os.Signal, 1) - // we will handle INT, TERM, QUIT here - signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT} + // we will handle INT, TERM, QUIT, SIGPIPE here + signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE} gosignal.Notify(c, signals...) go func() { interruptCount := uint32(0) for sig := range c { + if sig == syscall.SIGPIPE { + continue + } + go func(sig os.Signal) { logrus.Infof("Processing signal '%v'", sig) switch sig {