@cryptotaxi247 / kubo / commits / ff85e3839

raise default fd limit to 8192

fixes #6247 Really, we need a global _resource_ manager service that can sum requests from the datastore, libp2p, etc. for more file descriptors. However, we don't have that. License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>

Steven Allen committed Apr 25, 2019 at 18:28 UTC ff85e38392c2118906a4ff3198097ba3cd5e0162
1 file changed +49 -22
cmd/ipfs/util/ulimit.go
+49 -22
@@ -1,7 +1,6 @@
1 package util
2
3 import (
4 - "errors"
4 "fmt"
5 "os"
6 "strconv"
@@ -21,26 +20,25 @@ var (
20 setLimit func(uint64, uint64) error
21 )
22
24 -// maxFds is the maximum number of file descriptors that go-ipfs
25 -// can use. The default value is 2048. This can be overwritten by the
26 -// IPFS_FD_MAX env variable
27 -var maxFds = uint64(2048)
23 +// minimum file descriptor limit before we complain
24 +const minFds = 2048
25
29 -// setMaxFds sets the maxFds value from IPFS_FD_MAX
30 -// env variable if it's present on the system
31 -func setMaxFds() {
26 +// default max file descriptor limit.
27 +const maxFds = 8192
28 +
29 +// userMaxFDs returns the value of IPFS_FD_MAX
30 +func userMaxFDs() uint64 {
31 // check if the IPFS_FD_MAX is set up and if it does
32 // not have a valid fds number notify the user
33 if val := os.Getenv("IPFS_FD_MAX"); val != "" {
35 -
34 fds, err := strconv.ParseUint(val, 10, 64)
35 if err != nil {
36 log.Errorf("bad value for IPFS_FD_MAX: %s", err)
39 - return
37 + return 0
38 }
41 -
42 - maxFds = fds
39 + return fds
40 }
41 + return 0
42 }
43
44 // ManageFdLimit raise the current max file descriptor count
@@ -50,7 +48,12 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) {
48 return false, 0, nil
49 }
50
53 - setMaxFds()
51 + targetLimit := uint64(maxFds)
52 + userLimit := userMaxFDs()
53 + if userLimit > 0 {
54 + targetLimit = userLimit
55 + }
56 +
57 soft, hard, err := getLimit()
58 if err != nil {
59 return false, 0, err
@@ -65,23 +68,47 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) {
68 // the hard limit acts as a ceiling for the soft limit
69 // an unprivileged process may only set it's soft limit to a
70 // alue in the range from 0 up to the hard limit
68 - if err = setLimit(maxFds, maxFds); err != nil {
69 - if err != syscall.EPERM {
70 - return false, 0, fmt.Errorf("error setting: ulimit: %s", err)
71 + err = setLimit(targetLimit, targetLimit)
72 + switch err {
73 + case nil:
74 + newLimit = targetLimit
75 + case syscall.EPERM:
76 + // lower limit if necessary.
77 + if targetLimit > hard {
78 + targetLimit = hard
79 }
80
81 // the process does not have permission so we should only
82 // set the soft value
75 - if maxFds > hard {
76 - return false, 0, errors.New(
77 - "cannot set rlimit, IPFS_FD_MAX is larger than the hard limit",
83 + err = setLimit(targetLimit, hard)
84 + if err != nil {
85 + err = fmt.Errorf("error setting ulimit wihout hard limit: %s", err)
86 + break
87 + }
88 + newLimit = targetLimit
89 +
90 + // Warn on lowered limit.
91 +
92 + if newLimit < userLimit {
93 + err = fmt.Errorf(
94 + "failed to raise ulimit to IPFS_FD_MAX (%d): set to %d",
95 + userLimit,
96 + newLimit,
97 )
98 + break
99 }
100
81 - if err = setLimit(maxFds, hard); err != nil {
82 - return false, 0, fmt.Errorf("error setting ulimit wihout hard limit: %s", err)
101 + if userLimit == 0 && newLimit < minFds {
102 + err = fmt.Errorf(
103 + "failed to raise ulimit to minimum %d: set to %d",
104 + minFds,
105 + newLimit,
106 + )
107 + break
108 }
109 + default:
110 + err = fmt.Errorf("error setting: ulimit: %s", err)
111 }
112
86 - return true, maxFds, nil
113 + return newLimit > 0, newLimit, err
114 }