cmd/geth: graceful shutdown if disk is full (#22103)
Adding warnings of free disk space left and graceful shutdown when there is not enough space left. This also adds a flag datadir.minfreedisk which can be used to set the trigger for low disk space, and setting it to zero disables the check. Co-authored-by: Martin Holst Swende <martin@swende.se> Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
@ -26,17 +26,20 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/internal/debug"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -63,7 +66,7 @@ func Fatalf(format string, args ...interface{}) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func StartNode(stack *node.Node) {
|
||||
func StartNode(ctx *cli.Context, stack *node.Node) {
|
||||
if err := stack.Start(); err != nil {
|
||||
Fatalf("Error starting protocol stack: %v", err)
|
||||
}
|
||||
@ -71,6 +74,17 @@ func StartNode(stack *node.Node) {
|
||||
sigc := make(chan os.Signal, 1)
|
||||
signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer signal.Stop(sigc)
|
||||
|
||||
minFreeDiskSpace := eth.DefaultConfig.TrieDirtyCache
|
||||
if ctx.GlobalIsSet(MinFreeDiskSpaceFlag.Name) {
|
||||
minFreeDiskSpace = ctx.GlobalInt(MinFreeDiskSpaceFlag.Name)
|
||||
} else if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
|
||||
minFreeDiskSpace = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
|
||||
}
|
||||
if minFreeDiskSpace > 0 {
|
||||
go monitorFreeDiskSpace(sigc, stack.InstanceDir(), uint64(minFreeDiskSpace)*1024*1024)
|
||||
}
|
||||
|
||||
<-sigc
|
||||
log.Info("Got interrupt, shutting down...")
|
||||
go stack.Close()
|
||||
@ -85,6 +99,24 @@ func StartNode(stack *node.Node) {
|
||||
}()
|
||||
}
|
||||
|
||||
func monitorFreeDiskSpace(sigc chan os.Signal, path string, freeDiskSpaceCritical uint64) {
|
||||
for {
|
||||
freeSpace, err := getFreeDiskSpace(path)
|
||||
if err != nil {
|
||||
log.Warn("Failed to get free disk space", "path", path, "err", err)
|
||||
break
|
||||
}
|
||||
if freeSpace < freeDiskSpaceCritical {
|
||||
log.Error("Low disk space. Gracefully shutting down Geth to prevent database corruption.", "available", common.StorageSize(freeSpace))
|
||||
sigc <- syscall.SIGTERM
|
||||
break
|
||||
} else if freeSpace < 2*freeDiskSpaceCritical {
|
||||
log.Warn("Disk space is running low. Geth will shutdown if disk space runs below critical level.", "available", common.StorageSize(freeSpace), "critical_level", common.StorageSize(freeDiskSpaceCritical))
|
||||
}
|
||||
time.Sleep(60 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func ImportChain(chain *core.BlockChain, fn string) error {
|
||||
// Watch for Ctrl-C while the import is running.
|
||||
// If a signal is received, the import will stop at the next batch.
|
||||
|
Reference in New Issue
Block a user