Skip to content

Commit 4b7a24f

Browse files
authored
Merge pull request #6266 from ipfs/fix/fd-limit
raise default fd limit to 8192
2 parents e240316 + ff85e38 commit 4b7a24f

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+
// lower limit if necessary.
77+
if targetLimit > hard {
78+
targetLimit = hard
7179
}
7280

7381
// the process does not have permission so we should only
7482
// 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,
7897
)
98+
break
7999
}
80100

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
83108
}
109+
default:
110+
err = fmt.Errorf("error setting: ulimit: %s", err)
84111
}
85112

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

0 commit comments

Comments
 (0)