When sending SIGUSR1 to the daemon, it can crash because of a concurrent
map access panic, showing a stack trace involving dumpDaemon. It appears
it's not possible to recover from a concurrent map access panic. Since
it's important that SIGUSR1 not be a destructive operation, sadly the
best course of action I can think of is to remove this functionality.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,62 +0,0 @@ |
| 1 |
-package daemon |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "fmt" |
|
| 5 |
- "os" |
|
| 6 |
- "path/filepath" |
|
| 7 |
- "strings" |
|
| 8 |
- "time" |
|
| 9 |
- |
|
| 10 |
- "github.com/davecgh/go-spew/spew" |
|
| 11 |
- "github.com/pkg/errors" |
|
| 12 |
-) |
|
| 13 |
- |
|
| 14 |
-const dataStructuresLogNameTemplate = "daemon-data-%s.log" |
|
| 15 |
- |
|
| 16 |
-// dumpDaemon appends the daemon datastructures into file in dir and returns full path |
|
| 17 |
-// to that file. |
|
| 18 |
-func (d *Daemon) dumpDaemon(dir string) (string, error) {
|
|
| 19 |
- // Ensure we recover from a panic as we are doing this without any locking |
|
| 20 |
- defer func() {
|
|
| 21 |
- recover() |
|
| 22 |
- }() |
|
| 23 |
- |
|
| 24 |
- path := filepath.Join(dir, fmt.Sprintf(dataStructuresLogNameTemplate, strings.Replace(time.Now().Format(time.RFC3339), ":", "", -1))) |
|
| 25 |
- f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666) |
|
| 26 |
- if err != nil {
|
|
| 27 |
- return "", errors.Wrap(err, "failed to open file to write the daemon datastructure dump") |
|
| 28 |
- } |
|
| 29 |
- defer f.Close() |
|
| 30 |
- |
|
| 31 |
- dump := struct {
|
|
| 32 |
- containers interface{}
|
|
| 33 |
- names interface{}
|
|
| 34 |
- links interface{}
|
|
| 35 |
- execs interface{}
|
|
| 36 |
- volumes interface{}
|
|
| 37 |
- images interface{}
|
|
| 38 |
- layers interface{}
|
|
| 39 |
- imageReferences interface{}
|
|
| 40 |
- downloads interface{}
|
|
| 41 |
- uploads interface{}
|
|
| 42 |
- registry interface{}
|
|
| 43 |
- plugins interface{}
|
|
| 44 |
- }{
|
|
| 45 |
- containers: d.containers, |
|
| 46 |
- execs: d.execCommands, |
|
| 47 |
- volumes: d.volumes, |
|
| 48 |
- images: d.imageStore, |
|
| 49 |
- layers: d.layerStore, |
|
| 50 |
- imageReferences: d.referenceStore, |
|
| 51 |
- downloads: d.downloadManager, |
|
| 52 |
- uploads: d.uploadManager, |
|
| 53 |
- registry: d.RegistryService, |
|
| 54 |
- plugins: d.PluginStore, |
|
| 55 |
- names: d.nameIndex, |
|
| 56 |
- links: d.linkIndex, |
|
| 57 |
- } |
|
| 58 |
- |
|
| 59 |
- spew.Fdump(f, dump) // Does not return an error |
|
| 60 |
- f.Sync() |
|
| 61 |
- return path, nil |
|
| 62 |
-} |
| ... | ... |
@@ -22,12 +22,6 @@ func (d *Daemon) setupDumpStackTrap(root string) {
|
| 22 | 22 |
} else {
|
| 23 | 23 |
logrus.Infof("goroutine stacks written to %s", path)
|
| 24 | 24 |
} |
| 25 |
- path, err = d.dumpDaemon(root) |
|
| 26 |
- if err != nil {
|
|
| 27 |
- logrus.WithError(err).Error("failed to write daemon datastructure dump")
|
|
| 28 |
- } else {
|
|
| 29 |
- logrus.Infof("daemon datastructure dump written to %s", path)
|
|
| 30 |
- } |
|
| 31 | 25 |
} |
| 32 | 26 |
}() |
| 33 | 27 |
} |
| ... | ... |
@@ -41,12 +41,6 @@ func (d *Daemon) setupDumpStackTrap(root string) {
|
| 41 | 41 |
} else {
|
| 42 | 42 |
logrus.Infof("goroutine stacks written to %s", path)
|
| 43 | 43 |
} |
| 44 |
- path, err = d.dumpDaemon(root) |
|
| 45 |
- if err != nil {
|
|
| 46 |
- logrus.WithError(err).Error("failed to write daemon datastructure dump")
|
|
| 47 |
- } else {
|
|
| 48 |
- logrus.Infof("daemon datastructure dump written to %s", path)
|
|
| 49 |
- } |
|
| 50 | 44 |
} |
| 51 | 45 |
}() |
| 52 | 46 |
} |