From c6320c98345a9a945095eb9fb0b8413e6fcd5e72 Mon Sep 17 00:00:00 2001 From: Olivier Hervieu Date: Sun, 27 Feb 2022 15:38:11 +0100 Subject: [PATCH 1/4] eth, cmd: allow FdLimit to be set in config/command line (#24148) --- cmd/geth/main.go | 1 + cmd/geth/usage.go | 1 + cmd/utils/flags.go | 17 ++++++++++++++--- eth/ethconfig/config.go | 5 +++++ eth/ethconfig/gen_config.go | 6 ++++++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 94a0b16a8dbf..5314c59392c6 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -118,6 +118,7 @@ var ( utils.CacheSnapshotFlag, utils.CacheNoPrefetchFlag, utils.CachePreimagesFlag, + utils.FdLimitFlag, utils.ListenPortFlag, utils.MaxPeersFlag, utils.MaxPendingPeersFlag, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 417fba68923d..b685b63bba8f 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -119,6 +119,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.CacheSnapshotFlag, utils.CacheNoPrefetchFlag, utils.CachePreimagesFlag, + utils.FdLimitFlag, }, }, { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 7d11b0631a28..d4ceaade9fdc 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -433,6 +433,11 @@ var ( Name: "cache.preimages", Usage: "Enable recording the SHA3/keccak preimages of trie keys", } + FdLimitFlag = cli.IntFlag{ + Name: "fdlimit", + Usage: "Raise the open file descriptor resource limit (default = system fd limit)", + Value: math.MaxInt32, + } // Miner settings MiningEnabledFlag = cli.BoolFlag{ Name: "mine", @@ -1057,11 +1062,14 @@ func setLes(ctx *cli.Context, cfg *ethconfig.Config) { // MakeDatabaseHandles raises out the number of allowed file handles per process // for Geth and returns half of the allowance to assign to the database. -func MakeDatabaseHandles() int { +func MakeDatabaseHandles(userFdLimit int) int { limit, err := fdlimit.Maximum() if err != nil { Fatalf("Failed to retrieve file descriptor allowance: %v", err) } + if userFdLimit < limit { + limit = userFdLimit + } raised, err := fdlimit.Raise(uint64(limit)) if err != nil { Fatalf("Failed to raise file descriptor allowance: %v", err) @@ -1522,7 +1530,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) { cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 } - cfg.DatabaseHandles = MakeDatabaseHandles() + if ctx.GlobalIsSet(FdLimitFlag.Name) { + cfg.FdLimit = ctx.GlobalInt(FdLimitFlag.Name) + } + cfg.DatabaseHandles = MakeDatabaseHandles(cfg.FdLimit) if ctx.GlobalIsSet(AncientFlag.Name) { cfg.DatabaseFreezer = ctx.GlobalString(AncientFlag.Name) } @@ -1840,7 +1851,7 @@ func SplitTagsFlag(tagsFlag string) map[string]string { func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database { var ( cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 - handles = MakeDatabaseHandles() + handles = MakeDatabaseHandles(ctx.GlobalInt(FdLimitFlag.Name)) err error chainDb ethdb.Database diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 1dbd5a7f1fd8..bb7ad376dc6d 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -18,6 +18,7 @@ package ethconfig import ( + "math" "math/big" "os" "os/user" @@ -83,6 +84,7 @@ var Defaults = Config{ TrieDirtyCache: 256, TrieTimeout: 60 * time.Minute, SnapshotCache: 102, + FdLimit: math.MaxInt32, Miner: miner.Config{ GasCeil: 8000000, GasPrice: big.NewInt(params.GWei), @@ -169,6 +171,9 @@ type Config struct { SnapshotCache int Preimages bool + // FdLimit Tuning + FdLimit int + // Mining options Miner miner.Config diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 70a9649bff83..55e18be7140d 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -48,6 +48,7 @@ func (c Config) MarshalTOML() (interface{}, error) { TrieTimeout time.Duration SnapshotCache int Preimages bool + FdLimit int Miner miner.Config Ethash ethash.Config TxPool core.TxPoolConfig @@ -93,6 +94,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.TrieTimeout = c.TrieTimeout enc.SnapshotCache = c.SnapshotCache enc.Preimages = c.Preimages + enc.FdLimit = c.FdLimit enc.Miner = c.Miner enc.Ethash = c.Ethash enc.TxPool = c.TxPool @@ -142,6 +144,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { TrieTimeout *time.Duration SnapshotCache *int Preimages *bool + FdLimit *int Miner *miner.Config Ethash *ethash.Config TxPool *core.TxPoolConfig @@ -250,6 +253,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.Preimages != nil { c.Preimages = *dec.Preimages } + if dec.FdLimit != nil { + c.FdLimit = *dec.FdLimit + } if dec.Miner != nil { c.Miner = *dec.Miner } From 9fa8e0162509c56b4f4ec738e35a692aae76b922 Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Tue, 1 Mar 2022 09:41:01 +0800 Subject: [PATCH 2/4] eth/ethconfig: format code --- eth/ethconfig/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index bb7ad376dc6d..c1e85f46a959 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -84,7 +84,7 @@ var Defaults = Config{ TrieDirtyCache: 256, TrieTimeout: 60 * time.Minute, SnapshotCache: 102, - FdLimit: math.MaxInt32, + FdLimit: math.MaxInt32, Miner: miner.Config{ GasCeil: 8000000, GasPrice: big.NewInt(params.GWei), From acac749d6ec062d9e35a72e27acded10cbe37571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 7 Mar 2022 10:03:51 +0200 Subject: [PATCH 3/4] cmd, eth/ethconfig: simplify fdlimit arg, disallow toml --- cmd/geth/main.go | 2 +- cmd/geth/usage.go | 2 +- cmd/utils/flags.go | 20 ++++++++++---------- eth/ethconfig/config.go | 5 ----- eth/ethconfig/gen_config.go | 6 ------ 5 files changed, 12 insertions(+), 23 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 5314c59392c6..e4c41999e1ea 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -118,7 +118,7 @@ var ( utils.CacheSnapshotFlag, utils.CacheNoPrefetchFlag, utils.CachePreimagesFlag, - utils.FdLimitFlag, + utils.FDLimitFlag, utils.ListenPortFlag, utils.MaxPeersFlag, utils.MaxPendingPeersFlag, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index b685b63bba8f..1a1a73f56876 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -119,7 +119,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.CacheSnapshotFlag, utils.CacheNoPrefetchFlag, utils.CachePreimagesFlag, - utils.FdLimitFlag, + utils.FDLimitFlag, }, }, { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d4ceaade9fdc..7ff2dece2285 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -433,10 +433,9 @@ var ( Name: "cache.preimages", Usage: "Enable recording the SHA3/keccak preimages of trie keys", } - FdLimitFlag = cli.IntFlag{ + FDLimitFlag = cli.IntFlag{ Name: "fdlimit", Usage: "Raise the open file descriptor resource limit (default = system fd limit)", - Value: math.MaxInt32, } // Miner settings MiningEnabledFlag = cli.BoolFlag{ @@ -1062,13 +1061,17 @@ func setLes(ctx *cli.Context, cfg *ethconfig.Config) { // MakeDatabaseHandles raises out the number of allowed file handles per process // for Geth and returns half of the allowance to assign to the database. -func MakeDatabaseHandles(userFdLimit int) int { +func MakeDatabaseHandles(max int) int { limit, err := fdlimit.Maximum() if err != nil { Fatalf("Failed to retrieve file descriptor allowance: %v", err) } - if userFdLimit < limit { - limit = userFdLimit + if max != 0 && max < limit { // 0 is the default, don't warn in that case + if max < 64 { + log.Error("File descriptor limit invalid (<64)", "had", max, "updated", limit) + } else { + limit = max + } } raised, err := fdlimit.Raise(uint64(limit)) if err != nil { @@ -1530,10 +1533,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) { cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 } - if ctx.GlobalIsSet(FdLimitFlag.Name) { - cfg.FdLimit = ctx.GlobalInt(FdLimitFlag.Name) - } - cfg.DatabaseHandles = MakeDatabaseHandles(cfg.FdLimit) + cfg.DatabaseHandles = MakeDatabaseHandles(ctx.GlobalInt(FDLimitFlag.Name)) if ctx.GlobalIsSet(AncientFlag.Name) { cfg.DatabaseFreezer = ctx.GlobalString(AncientFlag.Name) } @@ -1851,7 +1851,7 @@ func SplitTagsFlag(tagsFlag string) map[string]string { func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database { var ( cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 - handles = MakeDatabaseHandles(ctx.GlobalInt(FdLimitFlag.Name)) + handles = MakeDatabaseHandles(ctx.GlobalInt(FDLimitFlag.Name)) err error chainDb ethdb.Database diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index c1e85f46a959..1dbd5a7f1fd8 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -18,7 +18,6 @@ package ethconfig import ( - "math" "math/big" "os" "os/user" @@ -84,7 +83,6 @@ var Defaults = Config{ TrieDirtyCache: 256, TrieTimeout: 60 * time.Minute, SnapshotCache: 102, - FdLimit: math.MaxInt32, Miner: miner.Config{ GasCeil: 8000000, GasPrice: big.NewInt(params.GWei), @@ -171,9 +169,6 @@ type Config struct { SnapshotCache int Preimages bool - // FdLimit Tuning - FdLimit int - // Mining options Miner miner.Config diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 55e18be7140d..70a9649bff83 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -48,7 +48,6 @@ func (c Config) MarshalTOML() (interface{}, error) { TrieTimeout time.Duration SnapshotCache int Preimages bool - FdLimit int Miner miner.Config Ethash ethash.Config TxPool core.TxPoolConfig @@ -94,7 +93,6 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.TrieTimeout = c.TrieTimeout enc.SnapshotCache = c.SnapshotCache enc.Preimages = c.Preimages - enc.FdLimit = c.FdLimit enc.Miner = c.Miner enc.Ethash = c.Ethash enc.TxPool = c.TxPool @@ -144,7 +142,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { TrieTimeout *time.Duration SnapshotCache *int Preimages *bool - FdLimit *int Miner *miner.Config Ethash *ethash.Config TxPool *core.TxPoolConfig @@ -253,9 +250,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.Preimages != nil { c.Preimages = *dec.Preimages } - if dec.FdLimit != nil { - c.FdLimit = *dec.FdLimit - } if dec.Miner != nil { c.Miner = *dec.Miner } From f96219e0c8690d2de4418a2e8e14fd8a671d9287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 7 Mar 2022 10:12:18 +0200 Subject: [PATCH 4/4] cnd/utils: make fdlimit setting nicer on the logs --- cmd/utils/flags.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 7ff2dece2285..98935e7e0fc4 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1066,12 +1066,18 @@ func MakeDatabaseHandles(max int) int { if err != nil { Fatalf("Failed to retrieve file descriptor allowance: %v", err) } - if max != 0 && max < limit { // 0 is the default, don't warn in that case - if max < 64 { - log.Error("File descriptor limit invalid (<64)", "had", max, "updated", limit) - } else { - limit = max - } + switch { + case max == 0: + // User didn't specify a meaningful value, use system limits + case max < 128: + // User specified something unhealthy, just use system defaults + log.Error("File descriptor limit invalid (<128)", "had", max, "updated", limit) + case max > limit: + // User requested more than the OS allows, notify that we can't allocate it + log.Warn("Requested file descriptors denied by OS", "req", max, "limit", limit) + default: + // User limit is meaningful and within allowed range, use that + limit = max } raised, err := fdlimit.Raise(uint64(limit)) if err != nil {