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 <jhonce@redhat.com>
| ... | ... |
@@ -127,6 +127,11 @@ func (cli *DaemonCli) start() (err error) {
|
| 127 | 127 |
stopc := make(chan bool) |
| 128 | 128 |
defer close(stopc) |
| 129 | 129 |
|
| 130 |
+ signal.Trap(func() {
|
|
| 131 |
+ cli.stop() |
|
| 132 |
+ <-stopc // wait for daemonCli.start() to return |
|
| 133 |
+ }) |
|
| 134 |
+ |
|
| 130 | 135 |
// warn from uuid package when running the daemon |
| 131 | 136 |
uuid.Loggerf = logrus.Warnf |
| 132 | 137 |
|
| ... | ... |
@@ -280,11 +285,6 @@ func (cli *DaemonCli) start() (err error) {
|
| 280 | 280 |
serveAPIWait := make(chan error) |
| 281 | 281 |
go api.Wait(serveAPIWait) |
| 282 | 282 |
|
| 283 |
- signal.Trap(func() {
|
|
| 284 |
- cli.stop() |
|
| 285 |
- <-stopc // wait for daemonCli.start() to return |
|
| 286 |
- }) |
|
| 287 |
- |
|
| 288 | 283 |
// after the daemon is done setting up we can notify systemd api |
| 289 | 284 |
notifySystem() |
| 290 | 285 |
|
| ... | ... |
@@ -18,15 +18,22 @@ import ( |
| 18 | 18 |
// * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is |
| 19 | 19 |
// skipped and the process is terminated immediately (allows force quit of stuck daemon) |
| 20 | 20 |
// * A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit. |
| 21 |
+// * Ignore SIGPIPE events. These are generated by systemd when journald is restarted while |
|
| 22 |
+// the docker daemon is not restarted and also running under systemd. |
|
| 23 |
+// Fixes https://github.com/docker/docker/issues/19728 |
|
| 21 | 24 |
// |
| 22 | 25 |
func Trap(cleanup func()) {
|
| 23 | 26 |
c := make(chan os.Signal, 1) |
| 24 |
- // we will handle INT, TERM, QUIT here |
|
| 25 |
- signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}
|
|
| 27 |
+ // we will handle INT, TERM, QUIT, SIGPIPE here |
|
| 28 |
+ signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE}
|
|
| 26 | 29 |
gosignal.Notify(c, signals...) |
| 27 | 30 |
go func() {
|
| 28 | 31 |
interruptCount := uint32(0) |
| 29 | 32 |
for sig := range c {
|
| 33 |
+ if sig == syscall.SIGPIPE {
|
|
| 34 |
+ continue |
|
| 35 |
+ } |
|
| 36 |
+ |
|
| 30 | 37 |
go func(sig os.Signal) {
|
| 31 | 38 |
logrus.Infof("Processing signal '%v'", sig)
|
| 32 | 39 |
switch sig {
|