diff --git a/src/ipft.c b/src/ipft.c index 2a82eee..b034f0f 100644 --- a/src/ipft.c +++ b/src/ipft.c @@ -11,6 +11,9 @@ #include #include #include +#include + +#include #include "ipft.h" @@ -73,7 +76,6 @@ opt_init(struct ipft_tracer_opt *opt) opt->perf_wakeup_events = 1; opt->regex = NULL; opt->script = NULL; - opt->set_rlimit = true; opt->verbose = false; } @@ -89,8 +91,6 @@ opt_dump(struct ipft_tracer_opt *opt) fprintf(stderr, "perf_page_cnt : %zu\n", opt->perf_page_cnt); fprintf(stderr, "perf_sample_period : %zu\n", opt->perf_sample_period); fprintf(stderr, "perf_wakeup_events : %u\n", opt->perf_wakeup_events); - fprintf(stderr, "set_rlimit : %s\n", - opt->set_rlimit ? "true" : "false"); fprintf(stderr, "============ End Options ============\n"); } @@ -121,6 +121,85 @@ opt_validate(struct ipft_tracer_opt *opt, bool list) return true; } +static int +get_nr_open(unsigned int *nr_openp) +{ + unsigned int nr_open; + + FILE *f = fopen("/proc/sys/fs/nr_open", "r"); + if (f == NULL) { + perror("Failed to open /proc/sys/fs/nr_open"); + return -1; + } + + if (fscanf(f, "%u", &nr_open) != 1) { + perror("Failed to read the value from /proc/sys/fs/nr_open"); + return -1; + } + + fclose(f); + + *nr_openp = nr_open; + + return 0; +} + +static int +do_set_rlimit(bool verbose) +{ + int error; + struct rlimit lim; + unsigned int nr_open; + + + /* + * Set locked memory limit to infinity + */ + if (verbose) { + fprintf(stderr, "Bumping RLIMIT_MEMLOCK (cur: RLIM_INFINITY, max: RLIM_INFINITY)\n"); + } + + lim.rlim_cur = RLIM_INFINITY; + lim.rlim_max = RLIM_INFINITY; + error = setrlimit(RLIMIT_MEMLOCK, &lim); + if (error == -1) { + perror("setrlimit"); + return -1; + } + + /* + * Get maximum possible value of open files + */ + error = get_nr_open(&nr_open); + if (error == -1) { + fprintf(stderr, "get_nr_open failed\n"); + return -1; + } + + /* + * Set file limit + */ + if (verbose) { + fprintf(stderr, "Bumping RLIMIT_MEMLOCK (cur: %u, max: %u)\n", nr_open, nr_open); + } + + lim.rlim_cur = nr_open; + lim.rlim_max = nr_open; + error = setrlimit(RLIMIT_NOFILE, &lim); + if (error == -1) { + fprintf(stderr, "setlimit failed (resource: RLIMIT_NOFILE, cur: %u, max: %u\n", nr_open, nr_open); + return -1; + } + + return 0; +} + +static int +debug_print(__unused enum libbpf_print_level level, const char *fmt, va_list ap) +{ + return vfprintf(stderr, fmt, ap); +} + int main(int argc, char **argv) { @@ -130,6 +209,7 @@ main(int argc, char **argv) struct ipft_tracer *t; struct ipft_tracer_opt opt; bool list = false; + bool set_rlimit = true; opt_init(&opt); @@ -177,7 +257,7 @@ main(int argc, char **argv) } if (strcmp(optname, "no-set-rlimit") == 0) { - opt.set_rlimit = false; + set_rlimit = false; break; } @@ -199,9 +279,20 @@ main(int argc, char **argv) } if (opt.verbose) { + /* Enable debug print for libbpf */ + libbpf_set_print(debug_print); + /* Print out all options user provided */ opt_dump(&opt); } + if (set_rlimit) { + error = do_set_rlimit(opt.verbose); + if (error == -1) { + fprintf(stderr, "do_set_rlimit failed\n"); + return -1; + } + } + error = tracer_create(&t, &opt); if (error == -1) { fprintf(stderr, "Failed to create tracer\n"); diff --git a/src/ipft.h b/src/ipft.h index fbcf4f1..e84fe1f 100644 --- a/src/ipft.h +++ b/src/ipft.h @@ -51,7 +51,6 @@ struct ipft_tracer_opt { size_t perf_page_cnt; uint64_t perf_sample_period; uint32_t perf_wakeup_events; - bool set_rlimit; bool verbose; }; diff --git a/src/tracer.c b/src/tracer.c index 5f05f1f..6b0c4a2 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -23,57 +22,6 @@ struct ipft_tracer { struct perf_buffer *pb; }; -static int -set_rlimit(struct ipft_symsdb *sdb) -{ - int error; - size_t nfiles; - struct rlimit lim; - - /* - * Rough estimations for various file descriptors like eBPF - * program, maps or perf events and kprobe events. This is - * the "required" number of file descriptors. - */ - nfiles = 32 + symsdb_get_sym2info_total(sdb); - - /* - * Set locked memory limit to infinity - */ - lim.rlim_cur = RLIM_INFINITY; - lim.rlim_max = RLIM_INFINITY; - error = setrlimit(RLIMIT_MEMLOCK, &lim); - if (error == -1) { - perror("setrlimit"); - return -1; - } - - /* - * Set file limit - */ - error = getrlimit(RLIMIT_NOFILE, &lim); - if (error == -1) { - perror("getrlimit"); - return -1; - } - - if (lim.rlim_cur < nfiles && lim.rlim_cur != RLIM_INFINITY) { - lim.rlim_cur = nfiles; - } - - if (lim.rlim_max != RLIM_INFINITY && lim.rlim_max < lim.rlim_cur) { - lim.rlim_max = lim.rlim_cur; - } - - error = setrlimit(RLIMIT_NOFILE, &lim); - if (error == -1) { - perror("setrlimit"); - return -1; - } - - return 0; -} - static struct { size_t total; size_t succeeded; @@ -392,12 +340,6 @@ bpf_create(struct bpf_object **bpfp, uint32_t mark, uint32_t mask, return 0; } -static int -debug_print(__unused enum libbpf_print_level level, const char *fmt, va_list ap) -{ - return vfprintf(stderr, fmt, ap); -} - static bool end = false; static void @@ -451,10 +393,6 @@ tracer_create(struct ipft_tracer **tp, struct ipft_tracer_opt *opt) int error; struct ipft_tracer *t; - if (opt->verbose) { - libbpf_set_print(debug_print); - } - t = calloc(1, sizeof(*t)); if (t == NULL) { fprintf(stderr, "Failed to allocate memory\n"); @@ -467,14 +405,6 @@ tracer_create(struct ipft_tracer **tp, struct ipft_tracer_opt *opt) return -1; } - if (opt->set_rlimit) { - error = set_rlimit(t->sdb); - if (error == -1) { - fprintf(stderr, "set_rlimit failed\n"); - return -1; - } - } - error = script_create(&t->script, opt->script); if (error == -1) { fprintf(stderr, "script_create failed\n");