diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index aa88187220b..2aed209add9 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -24,6 +24,7 @@ import ( fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" migrate "github.com/ipfs/go-ipfs/repo/fsrepo/migrations" + "github.com/hashicorp/go-multierror" "github.com/ipfs/go-ipfs-cmdkit" cmds "github.com/ipfs/go-ipfs-cmds" mprome "github.com/ipfs/go-metrics-prometheus" @@ -278,6 +279,10 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment break } + // The node will also close the repo but there are many places we could + // fail before we get to that. It can't hurt to close it twice. + defer repo.Close() + cfg, err := cctx.GetConfig() if err != nil { return err @@ -417,13 +422,14 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment // collect long-running errors and block for shutdown // TODO(cryptix): our fuse currently doesnt follow this pattern for graceful shutdown + var errs error for err := range merge(apiErrc, gwErrc, gcErrc) { if err != nil { - return err + errs = multierror.Append(errs, err) } } - return nil + return errs } // serveHTTPApi collects options, creates listener, prints status message and starts serving requests diff --git a/go.mod b/go.mod index 7fef560de5d..52368d6cdc0 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/fatih/color v1.7.0 // indirect github.com/fsnotify/fsnotify v1.4.7 github.com/gogo/protobuf v1.2.1 + github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/golang-lru v0.5.1 github.com/hsanjuan/go-libp2p-http v0.0.2 github.com/ipfs/dir-index-html v1.0.3 diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index 3a59108919e..a488bf817cf 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -128,6 +128,11 @@ test_expect_success "daemon with pipe eventually becomes live" ' test_fsh cat stdin_daemon_out || test_fsh cat stdin_daemon_err || test_fsh cat stdin_poll_apiout || test_fsh cat stdin_poll_apierr ' +test_expect_success "'ipfs daemon' cleans up when it fails to start" ' + test_must_fail ipfs daemon --routing=foobar && + test ! -e "$IPFS_PATH/repo.lock" +' + ulimit -S -n 512 TEST_ULIMIT_PRESET=1 test_launch_ipfs_daemon