Skip to content

Commit 653856e

Browse files
committed
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 <[email protected]>
1 parent 2385ccc commit 653856e

File tree

1 file changed

+49
-22
lines changed

1 file changed

+49
-22
lines changed

cmd/ipfs/util/ulimit.go

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package util
22

33
import (
4-
"errors"
54
"fmt"
65
"os"
76
"strconv"
@@ -21,26 +20,25 @@ var (
2120
setLimit func(uint64, uint64) error
2221
)
2322

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
2825

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 {
3231
// check if the IPFS_FD_MAX is set up and if it does
3332
// not have a valid fds number notify the user
3433
if val := os.Getenv("IPFS_FD_MAX"); val != "" {
35-
3634
fds, err := strconv.ParseUint(val, 10, 64)
3735
if err != nil {
3836
log.Errorf("bad value for IPFS_FD_MAX: %s", err)
39-
return
37+
return 0
4038
}
41-
42-
maxFds = fds
39+
return fds
4340
}
41+
return 0
4442
}
4543

4644
// ManageFdLimit raise the current max file descriptor count
@@ -50,7 +48,12 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) {
5048
return false, 0, nil
5149
}
5250

53-
setMaxFds()
51+
targetLimit := uint64(maxFds)
52+
userLimit := userMaxFDs()
53+
if userLimit > 0 {
54+
targetLimit = userLimit
55+
}
56+
5457
soft, hard, err := getLimit()
5558
if err != nil {
5659
return false, 0, err
@@ -65,23 +68,47 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) {
6568
// the hard limit acts as a ceiling for the soft limit
6669
// an unprivileged process may only set it's soft limit to a
6770
// 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+
err = fmt.Errorf("error setting: ulimit: %s", err)
77+
default:
78+
// lower limit if necessary.
79+
if targetLimit > hard {
80+
targetLimit = hard
7181
}
7282

7383
// the process does not have permission so we should only
7484
// 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",
85+
err = setLimit(targetLimit, hard)
86+
if err != nil {
87+
err = fmt.Errorf("error setting ulimit wihout hard limit: %s", err)
88+
break
89+
}
90+
newLimit = targetLimit
91+
92+
// Warn on lowered limit.
93+
94+
if newLimit < userLimit {
95+
err = fmt.Errorf(
96+
"failed to raise ulimit to IPFS_FD_MAX (%d): set to %d",
97+
userLimit,
98+
newLimit,
7899
)
100+
break
79101
}
80102

81-
if err = setLimit(maxFds, hard); err != nil {
82-
return false, 0, fmt.Errorf("error setting ulimit wihout hard limit: %s", err)
103+
if userLimit == 0 && newLimit < minFds {
104+
err = fmt.Errorf(
105+
"failed to raise ulimit to minimum %d: set to %d",
106+
minFds,
107+
newLimit,
108+
)
109+
break
83110
}
84111
}
85112

86-
return true, maxFds, nil
113+
return newLimit > 0, newLimit, err
87114
}

0 commit comments

Comments
 (0)