Skip to content

Commit 100d690

Browse files
gzliudanwanwiset25
authored andcommitted
common/fdlimit: cap on MacOS file limits, fixes ethereum#18994 (ethereum#19035)
1 parent 836302d commit 100d690

File tree

5 files changed

+25
-14
lines changed

5 files changed

+25
-14
lines changed

cmd/utils/flags.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,10 +821,11 @@ func MakeDatabaseHandles() int {
821821
if err != nil {
822822
Fatalf("Failed to retrieve file descriptor allowance: %v", err)
823823
}
824-
if err := fdlimit.Raise(uint64(limit)); err != nil {
824+
raised, err := fdlimit.Raise(uint64(limit))
825+
if err != nil {
825826
Fatalf("Failed to raise file descriptor allowance: %v", err)
826827
}
827-
return limit / 2 // Leave half for networking and other stuff
828+
return int(raised / 2) // Leave half for networking and other stuff
828829
}
829830

830831
// MakeAddress converts an account specified directly as a hex encoded string or

common/fdlimit/fdlimit_freebsd.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// You should have received a copy of the GNU Lesser General Public License
1515
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
1616

17+
//go:build freebsd
1718
// +build freebsd
1819

1920
package fdlimit
@@ -26,21 +27,24 @@ import "syscall"
2627

2728
// Raise tries to maximize the file descriptor allowance of this process
2829
// to the maximum hard-limit allowed by the OS.
29-
func Raise(max uint64) error {
30+
func Raise(max uint64) (uint64, error) {
3031
// Get the current limit
3132
var limit syscall.Rlimit
3233
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
33-
return err
34+
return 0, err
3435
}
3536
// Try to update the limit to the max allowance
3637
limit.Cur = limit.Max
3738
if limit.Cur > int64(max) {
3839
limit.Cur = int64(max)
3940
}
4041
if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
41-
return err
42+
return 0, err
43+
}
44+
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
45+
return 0, err
4246
}
43-
return nil
47+
return limit.Cur, nil
4448
}
4549

4650
// Current retrieves the number of file descriptors allowed to be opened by this

common/fdlimit/fdlimit_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestFileDescriptorLimits(t *testing.T) {
3636
if limit, err := Current(); err != nil || limit <= 0 {
3737
t.Fatalf("failed to retrieve file descriptor limit (%d): %v", limit, err)
3838
}
39-
if err := Raise(uint64(target)); err != nil {
39+
if _, err := Raise(uint64(target)); err != nil {
4040
t.Fatalf("failed to raise file allowance")
4141
}
4242
if limit, err := Current(); err != nil || limit < target {

common/fdlimit/fdlimit_unix.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// You should have received a copy of the GNU Lesser General Public License
1515
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
1616

17+
//go:build linux || darwin || netbsd || openbsd || solaris
1718
// +build linux darwin netbsd openbsd solaris
1819

1920
package fdlimit
@@ -22,21 +23,26 @@ import "syscall"
2223

2324
// Raise tries to maximize the file descriptor allowance of this process
2425
// to the maximum hard-limit allowed by the OS.
25-
func Raise(max uint64) error {
26+
// Returns the size it was set to (may differ from the desired 'max')
27+
func Raise(max uint64) (uint64, error) {
2628
// Get the current limit
2729
var limit syscall.Rlimit
2830
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
29-
return err
31+
return 0, err
3032
}
3133
// Try to update the limit to the max allowance
3234
limit.Cur = limit.Max
3335
if limit.Cur > max {
3436
limit.Cur = max
3537
}
3638
if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
37-
return err
39+
return 0, err
40+
}
41+
// MacOS can silently apply further caps, so retrieve the actually set limit
42+
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
43+
return 0, err
3844
}
39-
return nil
45+
return limit.Cur, nil
4046
}
4147

4248
// Current retrieves the number of file descriptors allowed to be opened by this

common/fdlimit/fdlimit_windows.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ import "errors"
2020

2121
// Raise tries to maximize the file descriptor allowance of this process
2222
// to the maximum hard-limit allowed by the OS.
23-
func Raise(max uint64) error {
23+
func Raise(max uint64) (uint64, error) {
2424
// This method is NOP by design:
2525
// * Linux/Darwin counterparts need to manually increase per process limits
2626
// * On Windows Go uses the CreateFile API, which is limited to 16K files, non
2727
// changeable from within a running process
2828
// This way we can always "request" raising the limits, which will either have
2929
// or not have effect based on the platform we're running on.
3030
if max > 16384 {
31-
return errors.New("file descriptor limit (16384) reached")
31+
return 0, errors.New("file descriptor limit (16384) reached")
3232
}
33-
return nil
33+
return max, nil
3434
}
3535

3636
// Current retrieves the number of file descriptors allowed to be opened by this

0 commit comments

Comments
 (0)