|
1 |
| -// This file was taken from: |
2 |
| -// https://github.com/OpenBazaar/openbazaar-go/blob/master/core/ulimit_non_unix.go |
| 1 | +// Copyright (C) 2019-2021, Ava Labs, Inc. All rights reserved. |
| 2 | +// See the file LICENSE for licensing terms. |
3 | 3 |
|
4 |
| -//go:build darwin || linux || netbsd || openbsd |
5 |
| -// +build darwin linux netbsd openbsd |
| 4 | +//go:build linux || netbsd || openbsd |
| 5 | +// +build linux netbsd openbsd |
6 | 6 |
|
7 | 7 | package ulimit
|
8 | 8 |
|
9 | 9 | import (
|
10 | 10 | "fmt"
|
11 |
| - "runtime" |
12 | 11 | "syscall"
|
| 12 | + |
| 13 | + "github.com/ava-labs/avalanchego/utils/logging" |
13 | 14 | )
|
14 | 15 |
|
15 |
| -// Set the file descriptor limit |
16 |
| -func Set(limit uint64) error { |
| 16 | +const DefaultFDLimit = 32 * 1024 |
| 17 | + |
| 18 | +// Set attempts to bump the Rlimit which has a soft (Cur) and a hard (Max) value. |
| 19 | +// The soft limit is what is used by the kernel to report EMFILE errors. The hard |
| 20 | +// limit is a secondary limit which the process can be bumped to without additional |
| 21 | +// privileges. Bumping the Max limit further would require superuser privileges. |
| 22 | +// If the current Max is below our recommendation we will warn on start. |
| 23 | +// see: http://0pointer.net/blog/file-descriptor-limits.html |
| 24 | +func Set(max uint64, log logging.Logger) error { |
17 | 25 | var rLimit syscall.Rlimit
|
18 | 26 | err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
19 | 27 | if err != nil {
|
20 | 28 | return fmt.Errorf("error getting rlimit: %w", err)
|
21 | 29 | }
|
22 | 30 |
|
23 |
| - oldMax := rLimit.Max |
24 |
| - if rLimit.Cur < limit { |
25 |
| - if rLimit.Max < limit { |
26 |
| - rLimit.Max = limit |
27 |
| - } |
28 |
| - rLimit.Cur = limit |
| 31 | + if max > rLimit.Max { |
| 32 | + return fmt.Errorf("error fd-limit: (%d) greater than max: (%d)", max, rLimit.Max) |
29 | 33 | }
|
30 | 34 |
|
31 |
| - // If we're on darwin, work around the fact that Getrlimit reports the wrong |
32 |
| - // value. See https://github.com/golang/go/issues/30401 |
33 |
| - if runtime.GOOS == "darwin" && rLimit.Cur > 10240 { |
34 |
| - // The max file limit is 10240, even though the max returned by |
35 |
| - // Getrlimit is 1<<63-1. This is OPEN_MAX in sys/syslimits.h. |
36 |
| - rLimit.Max = 10240 |
37 |
| - rLimit.Cur = 10240 |
38 |
| - } |
| 35 | + rLimit.Cur = max |
39 | 36 |
|
40 |
| - // Try updating the limit. If it fails, try using the previous maximum |
41 |
| - // instead of our new maximum. Not all users have permissions to increase |
42 |
| - // the maximum. |
| 37 | + // set new limit |
43 | 38 | if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit); err != nil {
|
44 |
| - rLimit.Max = oldMax |
45 |
| - rLimit.Cur = oldMax |
46 |
| - if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit); err != nil { |
47 |
| - return fmt.Errorf("error setting ulimit: %w", err) |
48 |
| - } |
| 39 | + return fmt.Errorf("error setting fd-limit: %w", err) |
| 40 | + } |
| 41 | + |
| 42 | + // verify limit |
| 43 | + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit); err != nil { |
| 44 | + return fmt.Errorf("error getting rlimit: %w", err) |
| 45 | + } |
| 46 | + |
| 47 | + if rLimit.Cur < DefaultFDLimit { |
| 48 | + log.Warn("fd-limit: (%d) is less than recommended: (%d) and could result in reduced performance", rLimit.Cur, DefaultFDLimit) |
49 | 49 | }
|
50 | 50 |
|
51 | 51 | return nil
|
|
0 commit comments