Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions cmd/utils/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"runtime"
"strings"
"syscall"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
Expand Down Expand Up @@ -71,6 +72,7 @@ func StartNode(stack *node.Node) {
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(sigc)
go ensureSufficientDiskSpace(sigc, stack.DataDir())
<-sigc
log.Info("Got interrupt, shutting down...")
go stack.Close()
Expand Down Expand Up @@ -312,3 +314,34 @@ func ExportPreimages(db ethdb.Database, fn string) error {
log.Info("Exported preimages", "file", fn)
return nil
}

// ensureSufficientDiskSpace guards Geth from hard crashing due to low disk space.
// It monitors remaining disk space under dataDir and gracefully exits Geth if the space is low.
func ensureSufficientDiskSpace(sigc chan os.Signal, dataDirPath string) {
monitorDiskSpace := func(sigc chan os.Signal, dataDirPath string) {
var stat syscall.Statfs_t
if err := syscall.Statfs(dataDirPath, &stat); err != nil {
log.Info("Could not list information about the disk containing path '%v': %v", dataDirPath, err)
sigc <- syscall.SIGTERM
return
}
MB := 1000000
avMemMB := int(stat.Bavail*uint64(stat.Bsize)) / MB
lowDiskWarning := 500
lowDiskCritical := 100
if avMemMB < lowDiskCritical {
log.Info("Available disk space critically low: %v MB remaining. Gracefully shutting down Geth to prevent database corruption.", avMemMB)
sigc <- syscall.SIGTERM
} else if avMemMB < lowDiskWarning {
log.Info("Node is running low on disk: %v remaining. It will terminate if disk space runs below %v MB.", avMemMB, lowDiskCritical)
}
}
for range time.Tick(5 * time.Second) {
select {
case <-sigc:
log.Info("Can't monitor disk space as the Node is being terminated.")
default:
go monitorDiskSpace(sigc, dataDirPath)
}
}
}