Skip to content

Commit

Permalink
fix crash when executor parent nomad process dies
Browse files Browse the repository at this point in the history
Fixes #5593

Executor seems to die unexpectedly after nomad agent dies or is
restarted.  The crash seems to occur at the first log message after
the nomad agent dies.

To ease debugging we forward executor log messages to executor.log as
well as to Stderr.  `go-plugin` sets up plugins with Stderr pointing to
a pipe being read by plugin client, the nomad agent in our case[1].
When the nomad agent dies, the pipe is closed, and any subsequent
executor logs fail with ErrClosedPipe and SIGPIPE signal.  SIGPIPE
results into executor process dying.

I considered adding a handler to ignore SIGPIPE, but hc-log library
currently panics when logging write operation fails[2]

This we opt to revert to v0.8 behavior of exclusively writing logs to
executor.log, while we investigate alternative options.

[1] https://github.com/hashicorp/nomad/blob/v0.9.0/vendor/github.com/hashicorp/go-plugin/client.go#L528-L535
[2] https://github.com/hashicorp/nomad/blob/v0.9.0/vendor/github.com/hashicorp/go-hclog/int.go#L320-L323
  • Loading branch information
Mahmood Ali committed Apr 23, 2019
1 parent 04d4d86 commit c07c0c8
Showing 1 changed file with 1 addition and 19 deletions.
20 changes: 1 addition & 19 deletions command/executor_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package command

import (
"encoding/json"
"io"
"os"
"strings"

Expand All @@ -11,17 +10,9 @@ import (
plugin "github.com/hashicorp/go-plugin"

"github.com/hashicorp/nomad/drivers/shared/executor"
"github.com/hashicorp/nomad/lib/circbufwriter"
"github.com/hashicorp/nomad/plugins/base"
)

const (
// circleBufferSize is the size of the in memory ring buffer used for
// go-plugin logging to stderr. When the buffer exceeds this size before
// flushing it will begin overwriting data
circleBufferSize = 64 * 1024
)

type ExecutorPluginCommand struct {
Meta
}
Expand Down Expand Up @@ -55,20 +46,11 @@ func (e *ExecutorPluginCommand) Run(args []string) int {
return 1
}

// If the client detatches from go-plugin it will block on logging to stderr.
// This buffered writer will never block on write, and instead buffer the
// writes to a ring buffer.
bufferedStderrW := circbufwriter.New(os.Stderr, circleBufferSize)

// Tee the logs to stderr and the file so that they are streamed to the
// client
out := io.MultiWriter(f, bufferedStderrW)

// Create the logger
logger := log.New(&log.LoggerOptions{
Level: hclog.LevelFromString(executorConfig.LogLevel),
JSONFormat: true,
Output: out,
Output: f,
})

plugin.Serve(&plugin.ServeConfig{
Expand Down

0 comments on commit c07c0c8

Please # to comment.