From fc7341499ab8b8131c904bb4a117b978ac3fbaf1 Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Sun, 24 Oct 2021 09:17:35 -0700 Subject: [PATCH] Increase open file limit to maximum possible value Opening a lot of kernel modules for processing requires high open-file-limit value. The default value is 1024 which is too low. Try to increase process limit to infinity first. If it does not work then try to increase soft limit to hard limit value. Closes #76 --- generator/kmod_test.go | 2 ++ generator/main.go | 2 ++ generator/util.go | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/generator/kmod_test.go b/generator/kmod_test.go index 830a06e0..c356b2e1 100644 --- a/generator/kmod_test.go +++ b/generator/kmod_test.go @@ -20,6 +20,8 @@ import ( func TestModuleNames(t *testing.T) { t.Parallel() + increaseOpenFileLimit() + ver, err := readKernelVersion() require.NoError(t, err) diff --git a/generator/main.go b/generator/main.go index aa74ea95..9f392e1b 100644 --- a/generator/main.go +++ b/generator/main.go @@ -65,6 +65,8 @@ func runGenerator() error { defer pprof.StopCPUProfile() } + increaseOpenFileLimit() + conf, err := readGeneratorConfig(*configFile) if err != nil { return err diff --git a/generator/util.go b/generator/util.go index 27debfc0..b04aaba1 100644 --- a/generator/util.go +++ b/generator/util.go @@ -1,6 +1,10 @@ package main -import "regexp" +import ( + "regexp" + + "golang.org/x/sys/unix" +) // parseProperties parses input in form of "PROP1=VAL1\nPROP2=VAL2\n..." into a map func parseProperties(data string) map[string]string { @@ -13,3 +17,35 @@ func parseProperties(data string) map[string]string { return result } + +// Opening a lot of module files in parallel requires high limit of open file descriptors +func increaseOpenFileLimit() { + limit := unix.Rlimit{ + Cur: unix.RLIM_INFINITY, + Max: unix.RLIM_INFINITY, + } + + // first try to set the process limit to infinity + if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &limit); err == nil { + // it worked! + return + } + + // if the current process unprivileged then the only thing we can do is to set soft limit to max limit value + + if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &limit); err != nil { + warning("unable to get open file limit: %v", err) + return + } + + if limit.Cur >= limit.Max { + return // nothing to increase + } + + debug("increasing open file limit %d->%d", limit.Cur, limit.Max) + limit.Cur = limit.Max + + if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &limit); err != nil { + warning("unable to increase open file limit: %v", err) + } +}