@@ -4,15 +4,19 @@ import (
44 "context"
55 "flag"
66 "fmt"
7+ "io/ioutil"
78 "log"
89 "net/http"
910 "os"
1011 "runtime/pprof"
1112 "runtime/trace"
13+ "strconv"
14+ "strings"
1215 "sync"
1316 "sync/atomic"
1417
1518 "github.com/distr1/distri/cmd/distri/internal/fuse"
19+ "golang.org/x/sys/unix"
1620 "golang.org/x/xerrors"
1721
1822 _ "github.com/distr1/distri/internal/oninterrupt"
2731 httpListen = flag .String ("listen" , "" , "host:port to listen on for HTTP" )
2832)
2933
34+ func bumpRlimitNOFILE () error {
35+ // The smaller of the two is the highest which Linux will let us set:
36+ // https://github.com/torvalds/linux/blob/2be7d348fe924f0c5583c6a805bd42cecda93104/kernel/sys.c#L1526-L1541
37+ var fileMax , nrOpen uint64
38+ {
39+ b , err := ioutil .ReadFile ("/proc/sys/fs/file-max" )
40+ if err != nil {
41+ return err
42+ }
43+ fileMax , err = strconv .ParseUint (strings .TrimSpace (string (b )), 0 , 64 )
44+ if err != nil {
45+ return err
46+ }
47+ }
48+ {
49+ b , err := ioutil .ReadFile ("/proc/sys/fs/nr_open" )
50+ if err != nil {
51+ return err
52+ }
53+ nrOpen , err = strconv .ParseUint (strings .TrimSpace (string (b )), 0 , 64 )
54+ if err != nil {
55+ return err
56+ }
57+ }
58+ max := fileMax
59+ if nrOpen < max {
60+ max = nrOpen
61+ }
62+ set := unix.Rlimit {
63+ Max : max ,
64+ Cur : max ,
65+ }
66+ return unix .Setrlimit (unix .RLIMIT_NOFILE , & set )
67+ }
68+
3069var atExit struct {
3170 sync.Mutex
3271 fns []func () error
@@ -96,6 +135,9 @@ func main() {
96135 "scaffold" : {scaffold },
97136 "install" : {install },
98137 "fuse" : {func (args []string ) error {
138+ if err := bumpRlimitNOFILE (); err != nil {
139+ log .Printf ("Warning: bumping RLIMIT_NOFILE failed: %v" , err )
140+ }
99141 join , err := fuse .Mount (args )
100142 if err != nil {
101143 return err
0 commit comments